设计模式
描述一个问题,然后描述这个问题的解决方法,并无数次的重复使用这个方法而不必重复劳动。
1. 概念
增加一个抽象层
划分变化与不变并把它们隔离开
目标:封装变化
2. 模式分类
23个模式分为三大类型:创建型、结构型、行为型。
创建型:用于创建对象。如:单件模式、工厂模式和构建器模式。
结构型:影响对象之间的连接方式。如:代理模式和适配器模式。
行为型:在程序中处理具有特定操作类型的对象。这些对象要封装执行的操作过程。如:命令模式、模板方法模式、状态模式、策略模式、职责链模式、观察者模式、多派遣模式和访问者模式。
3. 简化习语
1) 信使(messenger)
将所有的消息版本封装到一个对象中到处传递,而不是分开传递。
2) 收集参数(collecting parameter)
4. 单件模式
它是允许一个类只有一个实例的方法。主要是防止客户程序员获得任何控制对象生命期的权利。用这种方法声明的构造函数、赋值操作符、拷贝构造函数都是私有的。还必须决定如何去创建这个对象实例。
憜性初始化
单件的变体
定义静态对象的函数一定不能是内联的。
单件的另一种变体采用将一个对象的“单件角”从实现中分离出来。
对模板参数的静态依赖
单件对象很少用也很少出现,它用于替代全局变量。
5. 命令模式:选择操作
命令模式就是一个作为对象的函数,也就是一个函数对象。命令模式是携带行为信息的信使。
命令模式的主要特点:允许向一个函数或对象传递一个想要的动作。
常见的一个应用就是:在应用程序中“撤销操作”功能的实现。
作用之一:消除与事件处理的耦合。它可以避免程序中“正常代码”与事件代码间的耦合。
6. 消除对象耦合 (代理(proxy)模式和状态(state)模式)
代理(proxy)模式和状态(state)模式都是一个代理(surrogate)类。
基本思想:代理(surrogate)类派生自一个基类,由平行地派生自同一个基类的一个(proxy mode)或多个类(state mode)提供实际的实现。
用前端对象使后端对象履行其职责。
代理模式与状态模式之前的不同之处在于它们所解决的问题不同。
1) 代理模式:作为其他对象的前端
一般用途:
远程代理(Remote proxy)
虚拟代理(Virtual proxy)
保护代理(Protection proxy)
巧妙引用(Smart reference)
2) 状态模式:改变对象的行为
状态模式产生一个可以改变其类的对象,当发现在大部分或所有的函数都有条件代码时,用这种模式很有用。
这种模式下,前端对象生存期期间,可以切换后端对象,来实现相同的函数调用产生不同的行为。
对状态类的改变将会自劝地在所有的代友中进行传播,而不需要编辑这些类来完成。
7. 适配器(Adapter)模式
适配器(Adapter)模式接受一种类型并提供一个对其他类型的接口中。
模板方法是“坚持相同的代码”,而被覆盖的函数是“变化的代码”。
8. 模板方法(Template Method)模式
驱动应用程序运行的“引擎”就是模板方法模式。
9. 策略(Stategy)模式:运行时选择算法
这种模式有一个明显的好处:可以在程序运行时插入变化的代码。
10. 职责链(Chain of Responsibility)模式:尝试采用一系列策略模式
使用自动递归搜索链中的每一种策略来找到一种解决问题的策略。
11. 工厂(factory)模式:封装对象的创建
可能是所有设计模式中最有用的模式之一。
这个模式就是强制用一个通用的工厂来集中创建对象,而不允许将创建对象的代友散布于整个系统。这样就会在需要创建对象的时候只修改这个工厂就行了。
目标:
1)更好的组织代码,使得在创建对象时不需要选择准确的构造函数类型。
1) 多态工厂
如果不需要创建独立的工厂对象,尽可能的使用静态工厂方法模式。
2) 抽象工厂
3) 虚构造函数
12. 构建器(Builder)模式:创建复杂对象
目标:将对象的创建与它的“表示法”分开。
13. 观察者(Observer)模式
适用于解决:当某些其它对象状态改变时,如果一组对象都需要做相应的更新,那该怎么处理呢?
1) 内部类方法
2) 观察者模式举例
14. 多重派遣
用访问者模式进行多重派遣