设计模式学习笔记总结

来源:互联网 发布:2016全球互联网数据 编辑:程序博客网 时间:2024/05/21 03:58

一.创建型模式

1.工厂方法模式

clip_image004

抽象工厂角色:提供一个创建产品的接口

具体工厂角色:实现创建各类产品


与简单工厂模式的区别是,简单工厂是一个工厂类,没有继承自任何接口类。当要增加某种产品的时候,需要修改这个工厂类,不符合OCP原则。
而工厂方法模式是面向接口的,如果要增加一个产品,我们可以通过继承接口来增加一个可以制造该产品的工厂类,而不需要修改之前的工厂类。

 

应用场景 创建不同种类的产品

定义创建对象的接口,封装对象的创建过程。
具体化类的工作延迟到子类中 (实现的时候,编写一个工厂接口,再编写一个工厂实现,这样具体化类的工作就延迟到工厂实现这个类里面了)

 

2.抽象工厂模式

 

应用场景 要创建不同种类的产品,而且这些产品自身还分不同的版本

首先有个抽象工厂
抽象工厂下面有n个版本的具体工厂
每个版本的具体工厂负责创建对应版本的m个不同产品

 

3.单例模式

一个类只有一个instance

 

4.建造者模式

clip_image008


应用场景 产品比较复杂,需要分阶段构造;不同的产品生产阶段是一样的

首先有一个包含构建阶段的接口,不同的产品具体实现自己的各个构建阶段(接口的实现)
然后有一个Director,将具体的产品构建过程传给它之后,Director来负责构建流程的操作,即按照顺序执行各个构建阶段并返回产品
http://baike.baidu.com/link?url=6Lwn1hx74N8_zV6ae0mDEECi2KMmE2S_xriKWPB-QIW73wlIo4JCc1RiMG7W1fLZGMdznnV9uMEu-JtgRQB_rq

5.原型模式


UML

即克隆一个对象

 

二.结构型模式

1.桥接模式

应用场景 当一个系统由多个方面组成,每个方面又有自己的需求变化。这种多维度的变化适用桥接模式。

比如交通系统分车子和公路两方面,车子的类型可以变化,公路的总类也可以变化。

通过用 类的成员是另一个类的对象 这种包含组合的方式来解决这种多维度的变化
比如有个抽象车,下面有小汽车,公交车
有个抽象路,下面有城市街道路,高速路

其中抽象路里面有个成员叫车,类型是抽象车

这样每个维度的变化只需要在自己的那个维度里面修改而不涉及其他维度
Bridge模式是一个非常有用的模式,也非常复杂,它很好的符合了开放-封闭原则和优先使用对象,而不是继承这两个面向对象原则。

http://www.cnblogs.com/houleixx/archive/2008/02/23/1078877.html

另外标准叙述中的桥接模式分抽象化角色和实现化角色,抽象化角色将实现化角色当做一个成员
在上述例子中,路这个角色就是抽象化角色,车这个角色就是实现化角色
表达的意思是路的run函数实际上是调用车的run函数,具体怎么run,是定义在具体的车的run函数里面的

连接里面的后面加了个人这个角色,这个时候人成了抽象化角色,路成了实现化角色

 

2.适配器模式


将一个类的接口封装成适合于客户的接口

有两种实现:
类模式:adapter 公有继承目标接口类,私有继承提供者类    然后将提供者类提供的接口转换成目标接口
对象模式: 提供者类的对象是adapter的一个成员 

 

3.装饰模式

应用场景 需要给某个类增加功能的时候

角色:
抽象构件
具体构件(继承自抽象构件)
装饰角色(继承自抽象构件,并有一个具体构件的引用)
具体装饰(实现新增加的那个功能)

 

4.组合模式

应用场景 适用于树形结构

比如文件系统
component角色声明文件系统结构树中每一个节点的行为(添加 删除 获取某个文件 打开文件),即接口
left角色表示非文件夹文件,是component的一个实现,下面没有文件或者文件夹了
composite角色表示文件系统结构树中的每一个节点,也是component的一个实现,下面可以有n个composite作为其儿子

 

5.享元模式

应用场景 大量的对象有重复的属性,把重复的部分只保存一份,由Factory来管理这个重复的部分.客户端自己管理每个对象不同的部分,每个对象的相同部分有Factory提供
http://fengzl.iteye.com/blog/117129

每个对象分两个状态
内蕴状态->可共享部分,即上述重复的属性
外蕴状态->不可共享部分

抽象享元角色:所有的具体享元类的超类,规定出需要实现的公共接口。那些需要外蕴状态的操作可以通过方法的参数传入。抽象享元的接口使得享元变得可能,但是并不强制子类实行共享,因此并非所有的享元对象都是可以共享的。
具体享元角色:实现抽象享元角色所规定的接口。如果有内蕴状态的话,必须负责为内蕴状态提供存储空间。享元对象的内蕴状态必须与对象所处的周围环境无关,从而使得享元对象可以在系统内共享。复合享元角色是由具体享元角色通过复合而成。
--复合享元角色:复合享元角色所代表的对象是不可以共享的,但是可以分解成多个可以共享的具体享元角色。
享元工厂角色:负责创建和管理享元角色。本角色必须保证享元对象可以被系统适当地共享。当一个客户端对象调用一个享元对象时,享元工厂角色会检查系统中是否已经有一个符合要求的享元对象。如果有,享元工厂就提供这个已经有的享元对象,如果没有,享元工厂创建一个适当的享元对象。
客户端角色:需要维护一个对所有享元对象的引用。本角色需要自行存储所有享元对象的外蕴状态。

客户端中,以内蕴状态调用享元工厂,享元工厂查找该内蕴状态,找到返回;没查到将其插入共享池中再返回。客户端得到该对象后,用外蕴状态调用其业务方法Operation。
抽象享元包括一个operation的接口,一个表示内蕴的成员。

 

6.外观模式


应用场景 将多个类的相互操作封装起来,提供一个简单的接口供客户端使用
一个简单的例子是,编译器编译代码分词法分析,语法分析,语义分析等,将这些操作封装成编译操作,客户端直接调用这个编译操作即可。

 

7.代理模式


clip_image006

(1).职责清晰真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。
(3).高扩展性

代理类和委托类都实现相同的接口,客户端请求的时候将委托类的对象传给代理类,由代理类来执行相应方法(代理类在调用委托类的方法前后会做一些和业务逻辑不相干的事情)

 

三.行为模式

1.模板模式


其意图是定义一个操作的算法骨架,而将一些步骤延迟到子类中,可以不改变一个算法的结构即可以重新定义该算法的某些特定步骤
抽象类实现通用的算法逻辑,但是算法的具体细节由派生类提供

 

2.策略模式

 

抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
具体策略角色:包装了相关的算法和行为。
环境角色:持有一个策略类的引用,最终给客户端调用。

由客户端提供具体策略,然后交给环境角色去执行策略

 

3.状态模式

当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式来。
一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态。

环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。
抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

在状态的行为函数里面,本次行为操作完毕后,将环境角色的状态设置为下一状态。

 

4.观察者模式

MVC架构采用该模式,MFC,Structs采用该模式
又称发布订阅模式

两个角色
观察者(多个,接受通知,可以改变被观察者)
被观察者(一个,当改变的时候发送通知)

观察者必须向被观察者注册(订阅),所以被观察者要维护一个观察者列表,允许取消订阅

 

5.备忘录模式

Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。
Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
Caretaker(管理者):负责备忘录Memento,不能对Memento的内容进行访问或者操作。

 

6.中介者模式

设计时,同事类要向中介者类注册,消息格式可以设计为目标者+函数名+参数的形式
http://www.blogjava.net/jjshcc/archive/2010/09/09/331528.html

 

7.命令模式

 

抽象命令角色:提供一个命令的接口,比如开机
具体命令角色:通过调用接受者的具体方法来实现接口。比如调用电视机的开机,调用收音机的开机,调用电脑的开机
接受者角色:具体的命令执行者。比如电视,拥有具体的开机,关机,调频方法。比如电脑开机关机(没有调频)
调用者角色:命令集合的封装,比如开机,关机,调频等
客户端(组装者)角色:为不同的命令创建具体的接受者(可以不同),将这些具体命令封装到调用者
http://www.cnblogs.com/devinzhang/archive/2012/01/06/2315235.html

 

8,访问者模式

 

 

访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。
访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。
访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。

抽象访问者角色:提供访问具体元素时的接口visitElementA,visitElementB...
具体访问者角色:实现访问具体每一个元素时的操作
抽象元素角色:提供一个统一的接口accpet(visitor *)接受访问者的访问
具体元素角色:实现accpet方法,当访问者访问时,调用访问者中访问自己的那个方法
对象结构角色:将元素封装到一个元素池中,供客户端统一调用
客户端角色:向元素池添加具体要操作的元素,创建具体的访问者,把访问者传给对象结构角色,让它统一作用于对象池中的每一个对象

 

9.责任链模式

 

chain

比如 MFC的消息传递机制
抽象的Handler角色:提供处理请求的接口,设置和得到后继者的接口
具体的handler角色: 在实现处理请求的时候,判断自己能不能处理该请求,不能的话传给后继者继续处理,或者自己不能完全处理,也要传给后继者

 

10.迭代器模式

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

访问一个聚合对象的内容而无需暴露它的内部表示
支持对聚合对象的多种遍历
为遍历不同的聚合结构提供一个统一的接口

抽象迭代器角色:声明begin接口,end接口,getCurrentItem接口,getNext接口
具体迭代器角色:有个类型为聚合角色的属性成员,通过调用这个聚合角色的一些方法来实现上述接口
抽象聚合角色:声明迭代器需要的接口以及创建和获取迭代器的接口。
具体聚合角色:有自己的内部数据结构,需要实现提供给迭代器的接口。有一个迭代器属性成员。

 

11.解释器模式

clip_image008

http://hi.baidu.com/jonw000/item/82b0d64b57e5800ce8350418
感觉就是个递归结构
抽象的解释器角色:声明一个解释接口
终结符解释器角色:解释接口处理终结符
非终结符(规则)解释器角色:按照语法规则将表达式进行拆分,递归解释
上下文角色:提供一些全局的附加信息

比如表达式(a*b)/(a-b+2)
a,b,2是终结符
+ - * / 是规则,非终结符

原创粉丝点击