前言
目录
一 、图示符号说明
- 抽象类和具体类
- 参与者客户类(左)和绝对客户类(右)
- 类关系
- 伪代码注解
二、生成器(Builder)
- Builder
为创建一个Product对象的各个部件指定抽象接口。
- ConcreteBuilder
实现Builder的接口以构造和装配该产品的各个部件。
定义并明确它所创建的表示。
提供一个检索产品的接口。
- Director
构造一个使用Builder接口的对象。
- Product
表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程。
包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
协作
- 客户创建Director对象,并用它想要的Builder对象进行配置。
- 一旦产品部件被生成,导向器就会通知生成器。
- 生成器处理导向器的请求,并将部件添加到该产品中。
- 客户从生成器中检索产品。
- 它使你可以改变一个产品的内部表示:Builder对象向导向器提供一个构建产品的抽象接口。
- 它将构建代码和表示代码分开:每个子Builder包含了创建和装配一个特定产品的所有代码,然后不同的Director可以复用它以在相同部件集合的基础上构作不同的Product。
- 它使你可对构造过程进行更精细的控制:仅当产品完成时导向器才能从生成器中取回它。
- 装配和构造接口
- 产品没有抽象类
- 在Builder缺省的方法为空
三、模板方法(Template Method)
- AbstractClass
定义抽象的原语操作(primitive operation),具体的子类将重定义它们以实现一个算法的各步骤。
实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。
- ConcreteClass
实现原语操作以完成算法中与特定子类相关的步骤。
协作
四、观察者模式(Observer)
- Subject(目标)
目标知道它的观察者。可以有任意多个观察者观察同一个目标。
- Observer(观察者)
为那些在目标发生改变时需获得通知的对象定义一个更新接口。
- ConcreteSubject(具体目标)
将有关状态存入各ConcreteObserver对象。
当它的状态发生改变时,向它的各个观察者发出通知。
- ConcreteObserver(具体观察者)
维护一个指向ConcreteSubject对象的引用。
存储有关状态,这些状态应与目标的状态保持一致。
实现Observer的更新接口以使自身状态与目标的状态保持一致。
- 目标和观察者间的抽象耦合;
- 支持广播通信
- 意外的更新
- 创建目标到观察者之间的映射:当目标很多而观察者较少时,可以用hash表做映射关联。
- 观察多个目标:一个观察者依赖于多个目标时,目标对象可以将自己作为Update()操作的一个参数,让观察者知道应该去检查哪一个目标。多次连续操作效率低。
- 谁触发更新:一 在目标对象的SetState()(状态设定操作)中改变目标对象状态后自动调用Notify;二 让客户自己一系列操作更改完后在目标对象上调用Notify。客户可能会忘记调用,容易出错。
- 在观察者中避免对已删除目标的悬挂引用。当一个目标被删除时,让它通知它的观察者将该目标的引用复位。
- 在发出通知前确保目标的状态自身是一致的。
- 避免特定于观察者的更新协议——推/拉模型
- 显示地指定感兴趣的改变(Aspect& interest)
- 封装复杂的更新语义(更改管理器ChangeManager)
ChangeManager充当目标和观察者之间的中介者(Mediator模式),可使用Singleton模式来保证它是唯一的并且是可全局访问的。
五、中介者(Mediator)
- Mediator(中介者)
中介者定义一个接口用于与各同事(Colleague)对象通信。
- ConcreteMediator(具体中介者)
具体中介者通过协调各同事对象实现协作行为。
了解并维护它的各个同事。
- Colleague class(同事类)
每一个同事类都知道它的中介者对象。
每一个同事对象在需与其他的同事通信的时候,与它的中介者通信。
六、单件(Singleton)
- Singleton
定义一个Instance操作,允许客户访问它的唯一实例。Instance是一个类操作。
可能负责创建它自己的唯一实例。
- 对唯一实例的受控访问
- 缩小名空间,避免那些存储唯一实例的全局变量污染名空间
- 允许对操作和表示的精化:Singleton类可以有子类。
- 允许可变数目的实例:这个模式使得你易于改变你的想法,并允许Singleton类有多个实例。此外,你可以用相同的方法来控制应用所使用的实例数目。
- 比类操作更灵活
- 在Singleton的Instance操作中决定你要使用的是哪一个单件。
- 将Instance的实现从父类中分离出来在子类中实现。
- 使用一个静态的单件注册表,根据名字,单件实例键值对进行存储,在子类中注册供。比前面两种灵活。
七、工厂方法(Factory Method)
- Product
定义工厂方法所创建的对象的接口。
- ConcreteProduct
实现Product接口。
- Creator
声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
可以调用工厂方法以创建一个Product对象。
- ConcreteCreator
重定义工厂方法以返回一个ConcreteProduct实例。
- Abstract Factory经常用工厂方法来实现(抽象工厂中的工厂可以理解为工厂方法,相当于集合多个工厂方法);
- 工厂方法通常在Template Methods模式中被调用(一个方法可以同时是工厂方法和模板方法);
八、抽象工厂(Abstract Factory)
- AbstractFactory
声明一个创建抽象产品对象的操作接口。
- ConcreteFactory
实现创建具体产品对象的操作。
- AbstractProduct
为一类产品对象声明一个接口。
- ConcreteProduct
定义一个将被相应的具体工厂创建的产品对象。
实现AbstractProduct接口。
- Client
仅使用由AbstractFactory和AbstractProduct类声明的接口。
- 它分离了具体的类:客户通过工厂和产品的抽象接口操纵它们的实例。
- 它使得易于交换产品系列:一个具体工厂类在一个应用中仅出现一次,即在它初始化的时候,这使得改变一个应用的具体工厂变得容易。
- 它有利于产品的一致性:当一个系列的产品对象被设计在一起工作时,一个应用一次只能使用同一系列的产品对象。
- 难以支持新种类的产品:支持新产品就需要扩展工厂接口,这将涉及Abstract Factory类和所有子类的改变。解决方案:
- 将工作作为单件:一个应用中一般只需一个具体工厂(产品系列)
- 创建产品:使用工厂方法(Factory Method)实现。多个产品系列时可以考虑使用原型模式(Prototype),具体工厂使用产品系列中每一个产品的原型实例来初始化,且它通过复制它的原型来创建新的产品。在基于原型的方法中,使得不是每个新的产品系列都需要一个新的具体工厂类。
九、组成(Composite)
- Component
为组合中的对象声明接口。
在适当的情况下,实现所有类共有接口的缺省行为。
声明一个接口用于访问和管理Component的子组件。
(可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。
- Leaf
在组合中表示叶节点对象,叶节点没有子节点。
在组合中定义图元对象的行为。
- Composite
定义有子部件的那些部件的行为。
存储子部件。
在Component接口中实现与子部件有关的操作。
- Client
通过Component接口操纵组合部件的对象。
- 显式的父部件引用,同时父部件引用也应支持Chain of Responsibility模式。
- 共享组件:与Flyweight模式共同使用。
- 最大化Component接口:Component类尽可能涵盖Leaf和Composite类的公共操作。
- 声明管理子部件的操作:在透明性和安全性中作权衡,说明如上图。
- 在基类Component中实现一个Component列表:只有当该结构中子类的数目相对较少时,才值得使用这种方法。否则对叶节点来说会导致空间浪费。
- 子部件排序:可使用terator模式。
- 使用高速缓冲存贮改善性能:缓冲存储常用信息。
- 应该由谁删除Component:最好由Composite类负责删除其子节点。但有一种情况除外,即Leaf对象不会改变,因此可以被共享。
- 存贮组件组好用哪一种数据结构
十、装饰(Decorator)
- Component
定义一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent
定义一个对象,可以给这个对象添加一些职责。
- Decorator
维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
- ConcreteDecorator
向组件添加职责。
- 比静态继承更灵活:可以在运行时增加和删除装饰。
- 避免在层次结构高层的类有太多的特征:通过从简单的部件开始,逐步组合出复杂的功能。
- Decorator和它的Component不一样:一个被装饰的组件和这个组件是有差别的,因此不能采用对象标识去作为判断的依据(不依赖对象标识)。
- 有许多小对象
- 接口的一致性:装饰对象的接口必须与它所装饰的Component的接口是一致的。
- 省略抽象的Decorator类:当仅需要添加一个职责时,可以把Decorator向Component转发请求的职责合并到唯一的ConcreteDecorator中。
- 保持Component类的简单性
- 改变对象的外壳(采用Decorator模式)与改变对象的内核(采用Strategy模式)
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
- Abstraction
定义抽象类的接口。
维护一个指向Implementor类型对象的指针。
- RefinedAbstraction
扩充由Abstraction定义的接口。
- Implementor
定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个接口可以完全不同。一般来讲,Impementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作。
- ConcreteImplementor
实现Implementor接口并定义它的具体实现。
协作
Abstraction将Client的请求转发给它的Implementor对象。
优点
分离接口及其实现部分
提高可扩充性
实现细节对客户透明
提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
结构
参与者
- Iterator(迭代器)
迭代器定义访问和遍历元素的接口。
- ConcreteIterator(具体迭代器)
具体迭代器实现迭代器接口。
对该聚合遍历时跟踪当前位置。
- Aggregate(聚合)
聚合定义创建相应迭代器对象的接口。
- ConcreteAggregate(具体聚合)
具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例。
协作
ConcreteIterator跟踪聚合中的当前对象,并能计算出待遍历的后续对象。
效果
它支持以不同的方式遍历一个聚合:复杂的聚合可以使用多种方式进行遍历。
迭代器简化了聚合的接口:有了迭代器的遍历接口,聚合本身就不再需要类似的遍历接口了。
在同一个聚合上可以同时有多个遍历
实现
谁控制该迭代:当使用该迭代器的客户来控制迭代时,该迭代器称为一个外部迭代器(推荐)。而当由迭代器控制迭代时,该迭代器称为一个内部迭代器。
外部迭代器:var aIterator=aList.CreateIterator();
for(altertor.First();altertor.IsDone();altertor.Next()){.....}
内部迭代器:var aTraverser=new Traverser(aList); //aTraverser内部已经包含了aIterator,在aTraverser内部对aList进行遍历
aTraverser.Traverse();
谁定义遍历算法:由迭代器负责(推荐),或由聚合本身负责,然后用迭代器(这时可称为游标)来存储当前迭代的状态,指示当前位置。
附加的迭代器操作:迭代器的最小接口由First、Next、IsDone和CurrentItem操作组成。
相关模式
Composite:迭代器常被应用到像复合这样的递归结构上。
FactoryMethod:多态迭代器靠Factory Method来实例化适当的迭代器子类。
Memento:常与迭代器模式一起使用。迭代器可使用一个memento来捕获一个迭代的状态。迭代器在其内部存储memento。
相关资料:
- 《设计模式》
- 《大话设计模式》
作者:B.it
技术收录网站:核心技术(http://www.coretn.cn)
出处:http://www.cnblogs.com/ImBit/p/5492260.html
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。