总结记录23种设计模式类图和思想原理。
适应设计模式
1.Iterator模式
- 不管实现如何变化,都可以使用Iterator
2.Adapter模式
- 使用继承
- 使用委托
可以对现有的类进行适配
实际上,我们在让现有类适配新接口时,常常会有”只要将这里稍微修改下就可以的想法”一不留神就会修改现有代码
版本升级与兼容性
功能完全不同的类是无法使用的
交给子类
3.Tempalte Method(模板方法)
- 可以使逻辑处理通用化,当在模板方法中发现bug时,只需要修改模板方法即可
- 父类与子类紧密协作,子类需要理解抽象方法调用的时机,在看不到父类源码时,实现子类是比较困难的
- 父类与子类的一致性,LSP原则
4.Factory Method
- 框架与具体加工,框架无需修改
- 使用模式与开发人员沟通。使用模式设计类时,必须要向维护这些类的开发人员正确地传达这些设计模式的意图。否则,维护人员在修改设计时可能会违背设计者的最初意图
生成实例
5.Singleton模式
当存在多个实例时可能会相互影响,因此确保只有一个实例
何时生成实例
6.Prototype(原型模式)
对象种类繁多,无法将它们整合到一个类中时
难以根据类生成实例时
想解耦框架与生成实例时
一旦在代码中出现要使用的类的名字,就无法与该类分离开类,也就无法实现复用
7.Builder模式
时序图
Director类知道builder类,调用Builder类的方法来编写文档。但是它不知道具体是Builder类的哪个子类。只有不知道才能够替换
设计时能够决定的事和不能够决定的事
代码的阅读和修改方法
8.Abstract Factory抽象工厂
易于增加具体的工厂
难以增加新的零件
分开考虑
9.Bridge模式
将类的功能层次结构与实现层次结构分离
- 分开后更容易扩展,增加后的功能可以被所有实现使用
- 继承是强关联,委托是弱关联
10.Strategy(策略模式)
使用委托这种弱关联关系可以很方便地整体替换算法
程序运行中也可以切换策略
一致性
11.Composite模式
多个和单个的一致性
到处都存在递归结构
12.Decorate(装饰器模式)
接口(API)的透明性
在不改变被装饰物的前提下增加功能
可以动态地增加功能
只需要一些装饰物就可添加许多功能
访问数据结构
13.Visitor模式
双重分发
将处理从数据结构中分离出来
开闭原则
易于增加ConcreteVisitor,难以增加ConcreteElement
14.Chain of Responsibility
弱化请求者与处理者间的关系
可以动态地改变职责链
处理者专注自己的工作
简单化
15.Facade模式
接口API变少了
程序与外部的关联弱化了
当某个程序员得意地说出”啊,在调用那个类之前需要先调用这个类。在调用那个方法之前需要先在这个类中注册一下”的时候,就意味着需要引入facade模式了
对于那些能够明确用语言描述出来的知识,我们不应该将它们隐藏在自己的脑袋中,而是应该用代码将它们表现出来
16.Mediator(仲裁者)
- 当发生分散灾难时
- 通信线路的增加
- 哪些角色可以复用,依赖于特定应用程序就意味着难以复用
管理状态
17.Observer模式
体现出了可替换性
Observer的顺序
当Observer的行为会对Subject产生影响时
18.Memnto模式
注意Memnto中的不同接口类型,宽接口由于会暴露内部状态,因此只能由Originator使用
两种接口(API)和可见性
需要多少个Memento
Memento的有效期限是多久
划分Caretaker角色和Originator角色的意义。实现职责分担:变更为可以多次撤销;变更为不仅可以撤销,还可以将现在的状态保存在文件中
19.State模式
分而治之
依赖于状态的处理
应当是谁来管理状态的迁移
不会自相矛盾
易于增加新的状态
实例的多面性
避免浪费
20.Flyweight
对多个地方产生影响
不要让被共享的实例被垃圾回收器回收了
内存之外的资源
21.Proxy
使用代理人来提升处理速度
代理与委托
透明性
HTTP代理
各种proxy模式:Virtual Proxy,Remote Proxy,Access Proxy
用类来表现
22.Command
命令中应该包含哪些信息
保存历史记录
适配器
23.Interpreter
正则表达式
检索表达式
批处理语言
跳过标记还是读取标记