…
1. 创建型 - 如何生成一个实例
- 工厂方法
- 静态工厂
用户用抽象工厂,根据传入的参数生成不同的子类:
A = Factory.Create(“ClassA”);
B = Factory.Create(“ClassB”);
新增 ClassC 的时候,用户只用调整下参数,不需要关心 Factory 内部。
- 动态工厂
与静态工厂不同的是,用户获取到的也是个抽象产品类,用户不关心具体的子类:
Base = Factory.Create(“ClassA”);
Base = Factory.Create(“ClassB”);
用户只使用 Base 的相关方法,不关心内部到底是 ClassA 还是 ClassB
新增 ClassC 的时候,用户只用调整传入参数, 不需要关心 Factory 内部
- 抽象工厂
工厂方法只能创建一种产品,抽象工厂可以创建一个工厂,这个工厂可以创建一系列不同的类,每个工厂都会实现这些具体类:
FactoryA = AbstractFactory.create(“FactoryA”); // 用户用这个
FactoryB = AbstractFactory.create(“FactoryB”); // 或者用这个
// 以下代码都不变
BaseF = FactoryA.create(“BaseA”);
A = BaseF.creat(“ClassA”);
就是把工厂再抽象一层。
- 生成器
把一个复杂对象的生成步骤给抽象成一个个单独的步骤,每个步骤都由用户去控制:
bA = new BuilderA();
A = ba.op1().op2().op2().build(); // 一步步构建出来
Protobuf 用到了
原型
库提供一些原型,用户通过复制原型新建自己的类。用到少。单例
用的多。
2. 结构型 - 对象间如何组合,静态组合或动态组合
- 适配器
一个接口适配成另一个接口,一个类适配成另一个类。用户的参数和要用的接口不适配,可以增加一个适配器,让用户参数可以间接使用实际的接口。
用户持有 a,b, 要调用 methodA(a, b, c);
新建个接口 methodB(a,b), 内部调用 method(a,b,constC);
桥接
通过抽象层,分离具体的实现。用的比较少。组合
层级结构,或者属性结构的类的组织形式。装饰器
运行期动态给对象实例增加功能的方法,
一层层包裹原始接口,增加新的功能
A = DecoratorB(A);
A = DecoratorC(A);外观
库创建一个 Facade 类,用户使用这个外观(中介),跟库里边的多个组件打交道,完成一个复杂的操作;享元
库内部缓存一个固定的实例,用户使用接口获取新的实例的时候,实际用的是新建实例还是共享实例,由库内部控制,用户不用知道这些,比如 Guava 的缓存 Cache代理
对比适配器: 适配器只是转换接口,代理会增加额外的功能;
对比装饰器: 用户持有核心类,使用一层层装饰器增加功能; 代理时候用户不持有核心类,直接就是一个代理,库内部保存核心类,并增加一系列功能。
3. 行为型 - 算法和对象间的职责分配,对象如何通信、协作来完成一个整体任务
责任链
处理过程提前组成一个链,一个对象在这个链上流转,谁处理、谁结束、谁异常都提前规定好就行;命令
将一个请求或通知封装成一个对象,可以排队或执行撤销操作。比如socket的可读通知。解释器
解析引擎,给定一个特定领域的文法,使用引擎来执行特定的动作,比如用户只需要用SQL语言,由JDBC解释执行特定动作;迭代器
相当于抽象指针,来指向容器内部对象。中介
多个对象间都有通信,使用中介来集中处理这些通信,方便相互调用;备忘录
主要用于捕获一个对象的内部状态,以便在将来的某个时候恢复此状态。就是将状态封装成一个对象。观察者
发布-订阅模式。观察者提前设置监听,然后被动接收通知。状态
带有状态的对象,不同状态下会执行不同的动作。有限状态机,关键在与实现不同状态类、状态类之间的切换;策略
抽象出动作、算法,供不同的对象使用;模板方法
抽象类,父类定义骨架,客户端子类实现某些细节。访问者
访问复杂数据结构,操作数据对象,将这个操作封装成一个对象。
访问者模式的核心思想是为了访问比较复杂的数据结构,不去改变数据结构,而是把对数据的操作抽象出来。