原文:
设计模式大集合
最近要做架构了,得把设计模式整理一遍。因为这玩意,设计时能用就用,所以得明白啥时候用。不过要是成本太高了,或者根本低耦合没意义,就没必要用。这里列出使用场合(仅限于设计阶段),而且这文章不是给没学过的人看的,复习用的。
另外,并行设计模式不在本文范围内。
Creational Pattern:(创建类,描述怎样低耦合的创建对象)
Abstract Factory:
抽象工厂。当程序中对象分为并行的不同族(例如gnome和KDE),创建特定族的对象用此模式(例如创建一个窗口,要创建Gnome的就用GnomeAbstrctFactory.createWindow(),要创建KDE的就用KDEAbstractFactory.createWindow())
Builder:
当打算把对象实体和构造函数分开时,用这个模式。(构造函数独立成一个Builder对象,实现创建和实体的低耦合,例如一个Builder可以用来创建不同对象,一个对象可以用不同的Builder创建)
Factory Method:
基类规定了要创建一个类的对象,让子类决定创建什么。
Lazy Initialization:
一个对象的创建,一个值的计算,一个过程的调用需要推迟到实际需要的时候才执行时用这个。
Multiton:
Singleton是一个类只能创建一个对象。而Multiton是指保证一个类只能创建一个同名对象。(这个名,指map的key概念)
Object Pool:
对象池(Object Pool)是指提前创建好一批对象放在池子里,需要用的时候拿出来,用完了再放回去。执行过程中不新建不删除。
Prototype:
原型。拷贝一个新对象。有时候new不高效,或者创建对象时你不知道对象的内部(例如继承树很恐怖),一个特定状态的对象就是你想要的对象,如果赋予一些参数调用构造函数,然后设置属性会比较麻烦,或者要大批量的产生同样对象,用Prototype。
Resource acquisition is initialization(RAII)
如果在独占资源(例如写打开一个文件),一旦发生依常资源无法回收。RAII通过在析构函数里保证资源被回收了来确保无论是否发生依常,有打开,一定有关闭。(异常仍然会执行析构函数)
Singleton:
单例模式。一个类只允许创建一个实体。
Structural Pattern:
Adapter(Wrapper, Translator)
STL里叫这个适配器。一个类已经有一套接口了,你提供另外一套接口而不改变这个类本身得到另外一套功能。例如Heap就是建立在Vector基础上,Stack就是deque的接口封装(只允许deque的一端进出,并且不提供随机存取就是Stack)
Bridge:
基础类只提供接口,但接口不提供实现,而是通过Bridge对象调用具体不同的实现。这样基础类可以自由的变化,具体的实现也可以自由的变化。也就是说类上层逻辑和属性的变化不会影响方法的实现,方法实现的变化不会影响类的上层逻辑和属性。
Composite:
把一些具有相似操作的对象聚合到一起,像操作一个对象一样操作聚合,从而直接操作了所有对象。
Decorator:
通过继承一个类可以扩展功能,通过往原有的对象添加Decorator也可以实现同样的作用,而且可以动态的添加。
Facade:
一系列接口有共有的操作时,实现一个facade将共有的操作独立成统一的接口,通过调用这个共有接口就可以调用任何一个接口。
FlyWeight:
数据共享的。假设所有对象都有些共享数据作为自己的一部分,并且只需要读取,那么这个数据完全可以只保留一份,然后每个对象保留指针即可。例如点菜,菜谱里的菜只需要一份数据,每个桌子保存一系列菜指针。
Proxy:
代理。代理给使用这提供了一个假象的结构和数据内容,你可以操作代理的数据成员,但是代理会自动把操作转到它认为应该操作的地方。
Behavioral Patterns:
Chain of Responsibility:
多线程的话如果同时给一个对象发送两个Command就会有问题,为了避免这种情况,把命令对象串成一个串,接收对象挨个处理。再或者在中断模式下,你输入一个命令,计算机处理时间过长,导致你下个输入计算机没法响应,而你又想在上个响应后继续响应你之前的输入,这时也可以用到。
Command:
把一个对象对另一个对象的操作通过Commond解耦和,让接收对象可以接收不同的Command,并且Command应该都可以undo
Iterator:
最熟了的,STL里常用。为容器提供线性遍历。
Mediator:
协调者,多个对象之间要互相调用,Mediator能解耦和,然对象之间无关。
memento:
能够把对象的现在状态储存,一定时刻可以回滚重设对象状态。
Null Object:
可以避免产生取空指针错误。(不过。。。你老是取空对象也不是个事。。。一般用在通用判断,就是算法通用实现)
Observer(Publish、subscribe):
用一个对象监听多个对象,那一个对象发生变化,让多个对象一起跟着变化。
Servant:
服务员模式。一些类会共享一些操作,把这些操作独立出来实现个服务员,给这个服务员传递不同的参数它就完成通用的操作。
State:
一个对象里实现一个状态机,允许对象根据内部状态的变化而改变行为。
Strategy:
定义完成一个问题的不同的算法,可以由客户端动态选择。算法和客户端是独立变化的。
Template Method
流程一定了,但是实现方法有多种。在基类列出主要步骤,把每个步骤用虚函数表示,让子类继承实现不同版本的步骤。这样就可以形成流程统一,实现各异的方法。
Visitor:
往继承体系树里添加函数会很恐怖,但继承扩展实现功能很方便。Visitor使得相反,让继承体系树更容易添加函数操作。