基础笔记(二):设计模式摘录

 

前言

       收录一些本身在开发过程当中比较经常使用的模式,整理出来以便本身复习,毕竟熟才能生巧,才能变通,触类旁通。
设计模式在大多数灵活性好、可扩展性高、可移植的优秀程序中都有运用,好比界面展示层运用的MVC模式的主要关系就是由Observer(View-Model)、Composite(CompositeView嵌套视图)和Strategy(View-Controller)三个设计模式给出的。下面只列出模式的脉络大纲,若是想再拓展开且有时间的能够把经典砖头《设计模式》多嚼几遍。若是想了解个入门的,也能够看下《大话设计模式》。
 

目录

图示符号说明html

生成器(Builder)算法

模板方法(Template Method)设计模式

观察者模式(Observer)安全

中介者(Mediator)数据结构

单件(Singleton)函数

工厂方法(Factory Method)性能

抽象工厂(Abstract Factory)网站

组成(Composite)ui

装饰(Decorator)spa

桥接(Bridge)

迭代器(Iterator)

 

 

一 、图示符号说明

1.类图
  • 抽象类和具体类

  • 参与者客户类(左)和绝对客户类(右)

  • 类关系

  • 伪代码注解

2.对象图
 
 
 

2、生成器(Builder)

将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。
结构
参与者
  • Builder

为建立一个Product对象的各个部件指定抽象接口。

  • ConcreteBuilder

实现Builder的接口以构造和装配该产品的各个部件。

定义并明确它所建立的表示。

提供一个检索产品的接口。

  • Director

构造一个使用Builder接口的对象。

  • Product

表示被构造的复杂对象。ConcreteBuilder建立该产品的内部表示并定义它的装配过程。

包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

 协做

  • 客户建立Director对象,并用它想要的Builder对象进行配置。
  • 一旦产品部件被生成,导向器就会通知生成器。
  • 生成器处理导向器的请求,并将部件添加到该产品中。
  • 客户从生成器中检索产品。

效果
  1. 它使你能够改变一个产品的内部表示:Builder对象向导向器提供一个构建产品的抽象接口。
  2. 它将构建代码和表示代码分开:每一个子Builder包含了建立和装配一个特定产品的全部代码,而后不一样的Director能够复用它以在相同部件集合的基础上构做不一样的Product。
  3. 它使你可对构造过程进行更精细的控制:仅当产品完成时导向器才能从生成器中取回它。
实现
  1. 装配和构造接口
  2. 产品没有抽象类
  3. 在Builder缺省的方法为空
Builder模式和Abstract Factory 类似,主要区别在于Builder模式着重于一步步构建一个复杂对象,在最后一步返回产品,而Abstract Factory着重于多个系列的产品对象,产品是当即返回的。
 
 
 

3、模板方法(Template Method)

定义一个操做中算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类能够不改变一个算法的结构便可重定义该算法的某些特定步骤。
(模板方法:在方法体中一次性实现一个算法的不变部分,将可变的行为留给子类实现。)
结构
参与者
  • AbstractClass

定义抽象的原语操做(primitive operation),具体的子类将重定义它们以实现一个算法的各步骤。

实现一个模板方法,定义一个算法的骨架。该模板方法不只调用原语操做,也调用定义在AbstractClass或其余对象中的操做。

  • ConcreteClass

实现原语操做以完成算法中与特定子类相关的步骤。

协做

ConcreteClass靠AbstractClass来实现算法中不变的步骤。
 
效果
模板方法应该指明那些操做是钩子操做(能够被重定义)以及哪些是抽象操做(必须被重定义),子类编写者必须明确了解哪些操做是设计为有待重定义的。
 
相关模式
Factory Method:在子类现象的函数中常常调用Factory Method。
模板方法使用继承来改变算法的一部分,Strategy使用委托来改变整个算法。
 
 

4、观察者模式(Observer)

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,全部依赖于它的对象都会获得通知并被自动更新。
结构
参与者
  • Subject(目标)

目标知道它的观察者。能够有任意多个观察者观察同一个目标。

提供注册和删除观察者对象的接口。
  • Observer(观察者)

为那些在目标发生改变时需得到通知的对象定义一个更新接口。

  • ConcreteSubject(具体目标)

将有关状态存入各ConcreteObserver对象。

当它的状态发生改变时,向它的各个观察者发出通知。

  • ConcreteObserver(具体观察者)

维护一个指向ConcreteSubject对象的引用。

存储有关状态,这些状态应与目标的状态保持一致。

实现Observer的更新接口以使自身状态与目标的状态保持一致。

协做
优缺点
  1. 目标和观察者间的抽象耦合;
  2. 支持广播通讯
  3. 意外的更新
实现
  1. 建立目标到观察者之间的映射:当目标不少而观察者较少时,能够用hash表作映射关联。
  2. 观察多个目标:一个观察者依赖于多个目标时,目标对象能够将本身做为Update()操做的一个参数,让观察者知道应该去检查哪个目标。屡次连续操做效率低。
  3. 谁触发更新:一 在目标对象的SetState()(状态设定操做)中改变目标对象状态后自动调用Notify;二 让客户本身一系列操做更改完后在目标对象上调用Notify。客户可能会忘记调用,容易出错。
  4. 在观察者中避免对已删除目标的悬挂引用。当一个目标被删除时,让它通知它的观察者将该目标的引用复位。
  5. 在发出通知前确保目标的状态自身是一致的。
  6. 避免特定于观察者的更新协议——推/拉模型
  7. 显示地指定感兴趣的改变(Aspect& interest)
  8. 封装复杂的更新语义(更改管理器ChangeManager)

           ChangeManager充当目标和观察者之间的中介者(Mediator模式),可以使用Singleton模式来保证它是惟一的而且是可全局访问的。

 

     9.  结合目标类和观察者类(在不支持多重继承的语言中使用)
 
 

5、中介者(Mediator)

用一个中介对象来封装一系列的对象交互。中介者使各对象不须要显示地相互引用,从而使其耦合松散,并且能够独立地改变它们之间的交互。
(中介者充当一个中介以使组中的对象再也不相互显示引用。这些对象仅知道中介者,从而减小了相互链接的数目。)
结构
参与者
  • Mediator(中介者)

中介者定义一个接口用于与各同事(Colleague)对象通讯。

  • ConcreteMediator(具体中介者)

具体中介者经过协调各同事对象实现协做行为。

了解并维护它的各个同事。

  • Colleague class(同事类)

每个同事类都知道它的中介者对象。

每个同事对象在需与其余的同事通讯的时候,与它的中介者通讯。

 

协做
同事向一个中介者对象发送和接收请求。中介者在各同事间适当地转发请求以实现协做行为。
 
相关模式
Colleague可以使用Observer模式与Mediator通讯。
 
 
 

6、单件(Singleton)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。
结构
参与者
  • Singleton

定义一个Instance操做,容许客户访问它的惟一实例。Instance是一个类操做。

可能负责建立它本身的惟一实例。

协做
客户只能经过Singleton的Instance操做访问一个Singleton的实例。
优势
  1. 对惟一实例的受控访问
  2. 缩小名空间,避免那些存储惟一实例的全局变量污染名空间
  3. 容许对操做和表示的精化:Singleton类能够有子类。
  4. 容许可变数目的实例:这个模式使得你易于改变你的想法,并容许Singleton类有多个实例。此外,你能够用相同的方法来控制应用所使用的实例数目。
  5. 比类操做更灵活
    (惰性初始化:它的返回值直到被第一次访问时才建立和保存)
实现
保证一个惟一的实例:经常使用的方法是将建立这个实例的操做隐藏在一个类操做,如经过静态成员函数做为全局访问点公布出去。
建立Singleton类的子类:指向单件实例的变量必须用子类的实例初始化,方法有三种
  1. 在Singleton的Instance操做中决定你要使用的是哪个单件。
  2. 将Instance的实现从父类中分离出来在子类中实现。
  3. 使用一个静态的单件注册表,根据名字,单件实例键值对进行存储,在子类中注册供。比前面两种灵活。
 
 

7、工厂方法(Factory Method)

定义一个用于建立对象的接口,让子类决定将哪个类实例化,Factory Method使一个类的实例化延迟到其子类。
结构
参与者
  • Product

定义工厂方法所建立的对象的接口。

  • ConcreteProduct

实现Product接口。

  • Creator

声明工厂方法,该方法返回一个Product类型的对象。Creator也能够定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。

能够调用工厂方法以建立一个Product对象。

  • ConcreteCreator

重定义工厂方法以返回一个ConcreteProduct实例。

协做
Creator依赖于它的子类来定义工厂方法,以返回一个适当的ConcreteProduct实例。
 
相关模式
  1. Abstract Factory常常用工厂方法来实现(抽象工厂中的工厂能够理解为工厂方法,至关于集合多个工厂方法);
  2. 工厂方法一般在Template Methods模式中被调用(一个方法能够同时是工厂方法和模板方法);
 
 

8、抽象工厂(Abstract Factory)

提供一个建立一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
客户仅与抽象类定义的接口交互,而不使用特定的具体类的接口
结构
参与者
  • AbstractFactory

声明一个建立抽象产品对象的操做接口。

  • ConcreteFactory

实现建立具体产品对象的操做。

  • AbstractProduct

为一类产品对象声明一个接口。

  • ConcreteProduct

定义一个将被相应的具体工厂建立的产品对象。

实现AbstractProduct接口。

  • Client

仅使用由AbstractFactory和AbstractProduct类声明的接口。

协做
一般在运行时刻建立一个ConcreteFactory类的实例。这一具体的工厂建立具备特定实现的产品对象。为建立不一样的产品对象。客户应使用不一样的具体工厂。
Abstract Factory将产品对象的建立延迟到它的ConcreteFactory子类。
优缺点
  1. 它分离了具体的类:客户经过工厂和产品的抽象接口操纵它们的实例。
  2. 它使得易于交换产品系列:一个具体工厂类在一个应用中仅出现一次,即在它初始化的时候,这使得改变一个应用的具体工厂变得容易。
  3. 它有利于产品的一致性:当一个系列的产品对象被设计在一块儿工做时,一个应用一次只能使用同一系列的产品对象。
  4. 难以支持新种类的产品:支持新产品就须要扩展工厂接口,这将涉及Abstract Factory类和全部子类的改变。解决方案:
实现
  1. 将工做做为单件:一个应用中通常只需一个具体工厂(产品系列)
  2. 建立产品:使用工厂方法(Factory Method)实现。多个产品系列时能够考虑使用原型模式(Prototype),具体工厂使用产品系列中每个产品的原型实例来初始化,且它经过复制它的原型来建立新的产品。在基于原型的方法中,使得不是每一个新的产品系列都须要一个新的具体工厂类。
 
 

9、组成(Composite)

将对象组合成树形结构以表示“部分-总体”的层次关系。Composite使得用户对单个对象和组合对象的使用具备一致性。
结构
参与者
  • Component

为组合中的对象声明接口。

在适当的状况下,实现全部类共有接口的缺省行为。

声明一个接口用于访问和管理Component的子组件。

(可选)在递归结构中定义一个接口,用于访问一个父部件,并在合适的状况下实现它。

  • Leaf

在组合中表示叶节点对象,叶节点没有子节点。

在组合中定义图元对象的行为。

  • Composite

定义有子部件的那些部件的行为。

存储子部件。

在Component接口中实现与子部件有关的操做。

  • Client

经过Component接口操纵组合部件的对象。

协做
用户使用Component类接口与组合结构中的对象进行交互。若是接收者是一个叶节点,则直接处理请求。若是接收者是Composite,它一般将请求发给它的子部件,在转发请求以前或以后可能执行一些辅助操做。
 
实现
  1. 显式的父部件引用,同时父部件引用也应支持Chain of Responsibility模式。
  2. 共享组件:与Flyweight模式共同使用。
  3. 最大化Component接口:Component类尽量涵盖Leaf和Composite类的公共操做。
  4. 声明管理子部件的操做:在透明性和安全性中做权衡,说明如上图。
  5. 在基类Component中实现一个Component列表:只有当该结构中子类的数目相对较少时,才值得使用这种方法。不然对叶节点来讲会致使空间浪费。
  6. 子部件排序:可以使用terator模式。
  7. 使用高速缓冲存贮改善性能:缓冲存储经常使用信息。
  8. 应该由谁删除Component:最好由Composite类负责删除其子节点。但有一种状况除外,即Leaf对象不会改变,所以能够被共享。
  9. 存贮组件组好用哪种数据结构
相关模式
子部件-父部件链接用Chain of Responsibility模式
Composite模式常常和Decorator模式一块儿使用
Flyweight让你共享组件,但再也不能引用他们的父部件
Itertor可用来遍历Composite
Visitor将原本应该分布在Composite和Leaf类中的操做和行为局部化
 

10、装饰(Decorator)

动态地给一个对象添加一些额外的职责。就增长功能来讲,Decorator模式相比生成子类方式更为灵活。
结构
参与者
  • Component

定义一个对象接口,能够给这些对象动态地添加职责。

  • ConcreteComponent

定义一个对象,能够给这个对象添加一些职责。

  • Decorator

维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。

  • ConcreteDecorator

向组件添加职责。

协做
Decorator将请求转发给它的Component对象,并有可能在转发请求先后执行一些附加的动做。
 
优缺点
  1. 比静态继承更灵活:能够在运行时增长和删除装饰。
  2. 避免在层次结构高层的类有太多的特征:经过从简单的部件开始,逐步组合出复杂的功能。
  3. Decorator和它的Component不同:一个被装饰的组件和这个组件是有差异的,所以不能采用对象标识去做为判断的依据(不依赖对象标识)。
  4. 有许多小对象
实现
  1. 接口的一致性:装饰对象的接口必须与它所装饰的Component的接口是一致的。
  2. 省略抽象的Decorator类:当仅须要添加一个职责时,能够把Decorator向Component转发请求的职责合并到惟一的ConcreteDecorator中。
  3. 保持Component类的简单性
  4. 改变对象的外壳(采用Decorator模式)与改变对象的内核(采用Strategy模式)

 

采用Decorator模式

 

 

采用Strategy模式

 

 

 
 

 

11、桥接(Bridge)

将抽象部分与它的实现部分分离,使它们均可以独立地变化。

结构
参与者
  • Abstraction

定义抽象类的接口。

维护一个指向Implementor类型对象的指针。

  • RefinedAbstraction

扩充由Abstraction定义的接口。

  • Implementor

定义实现类的接口,该接口不必定要与Abstraction的接口彻底一致;事实上这两个接口能够彻底不一样。通常来说,Impementor接口仅提供基本操做,而Abstraction则定义了基于这些基本操做的较高层次的操做。

  • ConcreteImplementor

实现Implementor接口并定义它的具体实现。

 

协做

Abstraction将Client的请求转发给它的Implementor对象。

 

优势

分离接口及其实现部分

提升可扩充性

实现细节对客户透明

 

 

 

12、迭代器(Iterator)

 提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。

结构

参与者

  • 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                                           本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接。

相关文章
相关标签/搜索