设计模式简介

1. 背景

“设计模式”最初并不是出现在软件设计中,而是被用于建筑领域的设计中。

1977年美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫·亚历山大(Christopher Alexander)在他的著作《建筑模式语言:城镇、建筑、构造》中描述了一些常见的建筑设计问题,并提出了 253 种关于对城镇、邻里、住宅、花园和房间等进行设计的基本模式。

1990年软件工程界开始研讨设计模式的话题,后来召开了多次关于设计模式的研讨会。直到1995 年,艾瑞克·伽马(ErichGamma)、理査德·海尔姆(Richard Helm)、拉尔夫·约翰森(Ralph Johnson)、约翰·威利斯迪斯(John Vlissides)等 4 位作者合作出版了《设计模式:可复用面向对象软件的基础》一书,在此书中收录了 23 个设计模式,这是设计模式领域里程碑的事件,导致了软件设计模式的突破。这 4 位作者在软件开发领域里也以他们的“四人组”(Gang of Four,GoF)著称。

2. 概念

软件设计模式(Software Design Pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。

3. 优点

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。

正确使用设计模式具有以下优点:

  • 可以提高程序员的思维能力、编程能力和设计能力。
  • 使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
  • 使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

4. 七大原则

4.1 单一职责原则(Single Responsibility Principle,SRP)

一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分。每个类只负责自己的事情,而不是变成万能的。

如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱他的设计,当变化发生时,设计会遭受到意想不到的破坏;软件设计真正要做的许多内容就是发现职责并把那些职责相互分离。

4.2 接口隔离原则(Interface Segregation Principle,ISP)

一个类对另一个类的依赖应该建立在最小的接口上,各个类建立自己的专用接口,而不是建立万能接口。

使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。

4.3 开闭原则(Open Closed Principle,OCP)

开闭原则的意思是:对扩展开放,对修改关闭

扩展新类而不是修改旧类。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

4.4 依赖倒置原则(Dependence Inversion Principle,DIP)

这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

该原则可以说是面向对象设计的标志,编写时考虑的是如何对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口。

遵循这个原则可以带来面向对象技术所声称的可维护、可扩展、可复用、灵活性好。

4.5 里氏替换原则(Liskov Substitution Principle,LSP)

里氏代换原则是面向对象设计的基本原则之一。

里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。

里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

4.6 迪米特法则(Law of Demeter,LOD)

又称最少知道原则:只和你的直接朋友交谈,不跟“陌生人”说话(Talk only to your immediate friends and not to strangers)。一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

其含义是:如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

该原则其根本思想,是强调了类之间的松耦合;类之间的耦合越弱,越利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。在类的结构设计上,每一个类都应当尽量降低成员的访问权限。

4.7 合成复用原则(Composite Reuse Principle,CRP)

又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP),软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现

优先使用对象的合成/聚合将有助于你保持每个类被封装,并被击中在单个任务上,这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。

5. 分类

图片[1]-设计模式简介-深吸氧

5.1 创建型模式

这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。

它的主要特点是“将对象的创建与使用分离”,这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。

创建型模式分为五种:

  • 单例模式(Singleton Pattern)
  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 原型模式(Prototype Pattern)
  • 建造者模式(Builder Pattern)

5.2 结构型模式

把类或对象结合在一起形成一个更大的结构,这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。

它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。

结构型模式分为七种:

  • 代理模式(Proxy Pattern):一个类代表另一个类的功能
  • 适配器模式(Adapter Pattern):两个不兼容接口之间适配的桥梁
  • 装饰器模式(Decorator Pattern):向一个现有的对象添加新的功能,同时又不改变其结构
  • 桥接模式(Bridge Pattern):相同功能抽象化与实现化解耦,抽象与实现可以独立升级
  • 外观模式(Facade Pattern):向现有的系统添加一个接口,客户端访问此接口来隐藏系统的复杂性
  • 组合模式(Composite Pattern):相似对象进行组合,形成树形结构
  • 享元模式(Flyweight Pattern):尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象

5.3 行为型模式(Behavioral Pattern)

行为型模式负责类之间或对象间的交互和职责委派。分为类行为型模式和对象行为型模式:

  • 类行为型模式:使用继承关系在类之间分配行为,主要通过多态等方式来分配父类与子类的职责
  • 对象行为型模式:使用对象的聚合关联关系来分配行为,主要是通过对象关联等方式来分配两个或多个类的职责

根据合成复用原则,系统中要尽量使用关联关系来取代继承关系,因此大部分行为型设计模式都属于对象行为型设计模式。

行为型模式分为十一种:

  • 模板方法(Template Method)模式:父类定义算法骨架,某些实现放在子类
  • 策略(Strategy)模式:每种算法独立封装,根据不同情况使用不同算法策略
  • 状态(State)模式:每种状态独立封装,不同状态内部封装了不同行为
  • 命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开
  • 职责链(Chain of Responsibility)模式:所有处理者封装为链式结构,依次调用
  • 备忘录(Memento)模式:把核心信息抽取出来,可以进行保存
  • 解释器(Interpreter)模式:定义语法解析规则
  • 观察者(Observer)模式:维护多个观察者依赖,状态变化通知所有观察者
  • 中介者(Mediator)模式:取消类/对象的直接调用关系,使用中介者维护
  • 迭代器(Iterator)模式:定义集合数据的遍历规则
  • 访问者(Visitor)模式:分离对象结构,与元素的执行算法

除了模板方法模式和解释器模式是类行为型模式,其他的全部属于对象行为型模式

© 版权声明
THE END
请撒泡尿证明你到此一游
点赞6 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容