读完此书,寥寥几字总结一下各个模式。
设计模式是高于算法、低于软件工程的抽象层次,主要是把常见的软件架构设计问题抽象统一出一些模式,保证最基本的软件设计要求:解耦、可扩展、可维护等。书中分为创建型、结构型和行为型。类和对象的使用范围无感。如图所示:
0.创建型
Factory类,将创建对象的工作从Client处统一到factory中,Abstract Factory是将不同系列但是相同行为的数组对象放到了各个ConcreteFactory中,屏蔽了系列之间的差别和初始化工作。Factory Method去掉的系列的概念,只是封装同接口不同实现的产品的生成。Builder是可控过程(过程会很长很复杂)的创建,主要体现在可控创建过程,过程的控制和封装。
Prototype就是用clone代替构造函数,降低初始化的复杂度。
Singleton是保证全局单一实例,其实是对static的成员变量式的封装(将public static改变成private static+getter和一些初始化控制)。
1.结构型
Adapter是为了在使用新的接口时复用一些旧的实现,即用旧实现adapt新接口。
Bridge是基于这种观察,很多对象可以由两个定语限制,如在windows上的(#1)图片(#2)显示类。此时如果在一个类里同时封装windows和图片相关的函数,会造成子类数量不可控,而且逻辑并不清晰。可以使用Windows(#1)绘制API和图片(#2)绘制类加上Bridge的形式,解决这个问题。
Composite是使用相同接口定义出层叠结构的数据组合。最浅显的例子就是所有HTML标签大概都会有AbsoluteTag这个基类,其中有对子节点的引用。这样使用一个很优雅的方式定义了一个树形结构。
Decorator是为了使用相同接口为某个现有对象(不是类)添加与之不太相关的(不适宜作为成员函数)存在的功能。重点在相同接口和动态的添加分离性质。
Facade是将一个复杂子系统的初等(常用的简单)接口封装到一个类中,作为子系统的接口。其实可以看做是类封装数据操作这一思想在子系统上的的推广。
FlyWeight是保证重复数据在系统中只有一份,而其计算需要的环境因素作为参数传入。例子是文字编辑器中,每个文字是FlyWeight,计算文字所占面积的参数包括了这次引用时,文字所在位置等Context信息。这个的重点在把环境(Context)和内部因素(FlyWeight的成员变量)分离,只保存一份重复数据。
Proxy同样是使用相同接口添加功能(和Decorator一样),其所添加的功能有很大特色,与类所需实现的工作无关,更多是在丰富语言的数据控制(指针、I/O等)。是优化而非添加工作能力,而且更多的情况下是可以去掉的。没有Proxy,系统会慢速正常工作。没有Decorator,系统不会正常工作。
2.行为型
Interpreter是个文法解释器的抽象,不明白为什么会成为一个模式。
Template Method是将总体执行框架(抽象类中调用虚函数)在父类中确定,在子类中将某些步骤(虚函数)实现,最终实现整体功能。其中虚函数有两种用处,把具体实现下放到子类中;提供hook。
Chain of Responsibility是事件触发机制的抽象。可以用HTML(android)中的事件触发机制理解,每个对象在整体中(chain)有自己的上下文(其他对象),每个对象都可以对事件进行处理。此时,事件作为一个对象在chain上传递,直到某个组件对其进行处理。
Command是将函数作为对象存储起来。这种方法能将timeline上的函数调用固化到内存中,从而实现传递、Undo等功能。同时Command对象对Client屏蔽了真实执行者的逻辑。
Iterator是遍历的方法,将遍历作为一个共有功能抽象出来。
Mediator是将所有对象间的调用通信统一到一个对象中,通信逻辑全部在Mediator中,便于修改。避免混乱的交叉引用。Mediator不为每个通信提供一个函数接口,而是统一提供一个接口,通过标签和通信者区分通信过程。
Memento是为了将对象内部状态存储,最大的考虑是对外部对象(除使用Memento的对象和Memento之外)的访问控制。使用者将内部状态存入Memento,Memento对外无接口,只能存入容器中。而使用者可以通过Memento存储的信息进行状态传递和重置。
Observer是每个对象自己维护一个Observers列表,并在注册的事件发生时通知Observers。就是KVO采用的方法。
State是将不同状态对应的行为(同接口)封装到对象中,来代替if-else。Context可能作为参数传入State中。
Strategy将算法封装为对象,由Client决定何时使用。Strategy和Command都可以看做是对函数的封装,区别是Strategy的目标是替换,Command是统一接口。
Visitor是提供了双分派功能,即同一接口,调用什么函数由Visitor和Element的类型共同决定,为整体提供更抽象的接口。
网传很相似的 Bridge、Visitor、State和Strategy四个区别,在博文中有自我感觉良好的解释。