一、前言
设计模式是解决问题的方案,学习现有的设计模式可以做到经验复用。拥有设计模式词汇,在沟通时就能用更少的词汇来讨论,并且不需要了解底层细节。
#二、创建型
- 单例
- 简单工厂
- 工厂方法
- 抽象工厂
- 生成器
- 原型模式
#三、行为型
- 责任链
- 命令
- 解释器
- 迭代器
- 中介者
- 备忘录
- 观察者
- 状态
- 策略
- 模板方法
- 访问者
- 空对象
#四、结构型
- 适配器
- 桥接
- 组合
- 装饰
- 外观
- 享元
- 代理
单例(Singleton)
#Intent
确保一个类只有一个实例,并提供该实例的全局访问点。
#Class Diagram
使用一个私有构造函数、一个私有静态变量以及一个公有静态函数来实现。
私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。
简单工厂(Simple Factory)
#Intent
在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。
#Class Diagram
简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化。
这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。
工厂方法(Factory Method)
#Intent
定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。
#Class Diagram
在简单工厂中,创建对象的是另一个类,而在工厂方法中,是由子类来创建对象。
抽象工厂(Abstract Factory)
#Intent
提供一个接口,用于创建 相关的对象家族 。
#Class Diagram
抽象工厂模式创建的是对象家族,也就是很多对象而不是一个对象,并且这些对象是相关的,也就是说必须一起创建出来。而工厂方法模式只是用于创建一个对象,这和抽象工厂模式有很大不同。
抽象工厂模式用到了工厂方法模式来创建单一对象,AbstractFactory 中的 createProductA() 和 createProductB() 方法都是让子类来实现,这两个方法单独来看就是在创建一个对象,这符合工厂方法模式的定义。
至于创建对象的家族这一概念是在 Client 体现,Client 要通过 AbstractFactory 同时调用两个方法来创建出两个对象,在这里这两个对象就有很大的相关性,Client 需要同时创建出这两个对象。
从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂方法模式使用了继承。
生成器(Builder)
#Intent
封装一个对象的构造过程,并允许按步骤构造。
#Class Diagram
原型模式(Prototype)
#Intent
使用原型实例指定要创建对象的类型,通过复制这个原型来创建新对象。
#Class Diagram
责任链(Chain Of Responsibility)
#Intent
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链发送该请求,直到有一个对象处理它为止。
#Class Diagram
- Handler:定义处理请求的接口,并且实现后继链(successor)
命令(Command)
#Intent
将命令封装成对象中,具有以下作用:
- 使用命令来参数化其它对象
- 将命令放入队列中进行排队
- 将命令的操作记录到日志中
- 支持可撤销的操作
#Class Diagram
- Command:命令
- Receiver:命令接收者,也就是命令真正的执行者
- Invoker:通过它来调用命令
- Client:可以设置命令与命令的接收者
解释器(Interpreter)
#Intent
为语言创建解释器,通常由语言的语法和语法分析来定义。
#Class Diagram
- TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression。
- Context:上下文,包含解释器之外的一些全局信息。
迭代器(Iterator)
#Intent
提供一种顺序访问聚合对象元素的方法,并且不暴露聚合对象的内部表示。
#Class Diagram
- Aggregate 是聚合类,其中 createIterator() 方法可以产生一个 Iterator;
- Iterator 主要定义了 hasNext() 和 next() 方法;
- Client 组合了 Aggregate,为了迭代遍历 Aggregate,也需要组合 Iterator。
中介者(Mediator)
#Intent
集中相关对象之间复杂的沟通和控制方式。
#Class Diagram
- Mediator:中介者,定义一个接口用于与各同事(Colleague)对象通信。
- Colleague:同事,相关对象
备忘录(Memento)
#Intent
在不违反封装的情况下获得对象的内部状态,从而在需要时可以将对象恢复到最初状态。
#Class Diagram
- Originator:原始对象
- Caretaker:负责保存好备忘录
- Memento:备忘录,存储原始对象的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。
观察者(Observer)
#Intent
定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。
主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。
#Class Diagram
主题(Subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。
观察者(Observer)的注册功能需要调用主题的 registerObserver() 方法。
状态(State)
#Intent
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它所属的类。
#Class Diagram
策略(Strategy)
#Intent
定义一系列算法,封装每个算法,并使它们可以互换。
策略模式可以让算法独立于使用它的客户端。
#Class Diagram
- Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。
- Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。
模板方法(Template Method)
#Intent
定义算法框架,并将一些步骤的实现延迟到子类。
通过模板方法,子类可以重新定义算法的某些步骤,而不用改变算法的结构。
访问者(Visitor)
#Intent
为一个对象结构(比如组合结构)增加新能力。
#Class Diagram
- Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作
- ConcreteVisitor:具体访问者,存储遍历过程中的累计结果
- ObjectStructure:对象结构,可以是组合结构,或者是一个集合。
空对象(Null)
#Intent
使用什么都不做
的空对象来代替 NULL。
一个方法返回 NULL,意味着方法的调用端需要去检查返回值是否是 NULL,这么做会导致非常多的冗余的检查代码。并且如果某一个调用端忘记了做这个检查返回值,而直接使用返回的对象,那么就有可能抛出空指针异常。
适配器(Adapter)
#Intent
把一个类接口转换成另一个用户需要的接口。
桥接(Bridge)
#Intent
将抽象与实现分离开来,使它们可以独立变化。
组合(Composite)
#Intent
将对象组合成树形结构来表示“整体/部分”层次关系,允许用户以相同的方式处理单独对象和组合对象。
装饰(Decorator)
#Intent
为对象动态添加功能。
外观(Facade)
#Intent
提供了一个统一的接口,用来访问子系统中的一群接口,从而让子系统更容易使用。
享元(Flyweight)
#Intent
利用共享的方式来支持大量细粒度的对象,这些对象一部分内部状态是相同的。
代理(Proxy)
#Intent
控制对其它对象的访问。