基于设计模式的学习之旅Word下载.docx
- 文档编号:16584375
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:42
- 大小:1.67MB
基于设计模式的学习之旅Word下载.docx
《基于设计模式的学习之旅Word下载.docx》由会员分享,可在线阅读,更多相关《基于设计模式的学习之旅Word下载.docx(42页珍藏版)》请在冰豆网上搜索。
A、一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
B、各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
C、控制子类扩展。
点击下载“文档以及源码下载”
欢迎转载,请注明出处“
基于设计模式的学习之旅-----访问者模式
1、初始访问者模式
2、什么是访问者模式
表示一个作用于某对象结构中的各元素的操作。
它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
年会,每个小组表演节目
ITeam、IVisitor、CompanyObjectStructure、StudioTeam、ServerTeam、AnnualVisitor
使用访问者模式:
ITeam
StudioTeam
IVisitor
AnnualVisitor
CompanyObjectStructure
PatternRun
非访问者模式实现:
AnnualCompany
NoPatternRun
Visitor(访问者,如IVisitor)
ConcreteVisitor(具体访问者,如AnnualVisitor、MidAutumnVisitor)
Element(元素,如ITeam)
ConcreteElement(具体元素,如ServerTeam)
ObjectStructure(对象结构,如CompanyObjectStructure)
A、访问者模式使得易于增加新的操作。
访问者使得增加依赖于复杂对象结构的构件的操作变得容易了。
仅需增加一个新的访问者即可在一个对象结构上定义一个新的操作。
相反,如果每个功能都分散在多个类之上的话,定义新的操作时必须修改每一类。
B、访问者集中相关的操作而分离无关的操作。
相关的行为不是分布在定义该对象结构的各个类上,而是集中在一个访问者中。
无关行为却被分别放在它们各自的访问者子类中。
这就既简化了这些元素的类,也简化了在这些访问者中定义的算法。
所有与它的算法相关的数据结构都可以被隐藏在访问者中。
C、增加新的ConcreteElement类很困难。
Visitor模式使得难以增加新的Element的子类。
每添加一个新的ConcreteElement都要在Vistor中添加一个新的抽象操作,并在每一个ConcretVisitor类中实现相应的操作。
D、通过类层次进行访问。
一个迭代器(参见Iterator(5.4))可以通过调用节点对象的特定操作来遍历整个对象结构,同时访问这些对象。
但是迭代器不能对具有不同元素类型的对象结构进行操作。
E、累积状态。
当访问者访问对象结构中的每一个元素时,它可能会累积状态。
F、破坏封装。
访问者方法假定ConcreteElement接口的功能足够强,足以让访问者进行它们的工作。
结果是,该模式常常迫使你提供访问元素内部状态的公共操作,这可能会破坏它的封装性。
A、一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
B、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。
Visitor使得你可以将相关的操作集中起来定义在一个类中。
当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
C、定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。
改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。
如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
基于设计模式的学习之旅-----命令模式
1、初始命令模式
小时候家里面用的是黑白电视,每次想换台或者调声音大小的时候都得跑到电视边上,通过直接调电视按钮的方式来操作。
如果在大冬天,从被窝里面爬出来,换台是个痛苦的事情。
随着时代的发展,现在大家都幸福了。
都用上彩电了,每个彩电都有对应的遥控器,可以远程的通过遥控器来操作了。
这其实就是一种命令模式的体现,用户通过执行遥控器上的各个按钮命令来远程操作电视。
如:
首先,遥控器和电视是配丢的。
用户如果想调节电视声音大小,只需要按声音大小按钮。
遥控器收到这个信息,就告诉电视,让电视调整声音大小。
每一个遥控器上的按钮都是告诉电视去执行一个事情。
2、什么是命令模式
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;
对请求排队或记录请求日志,以及支持可撤消的操作。
场景一:
通过遥控板发命令方式控制彩色电视
场景二:
直接通过触发按钮方式控制黑白电视
4、1涉及到的类
AbstractCommand(抽象的命令)、ChangeChannelCommand,TurnDownCommand,TurnUpCommand(具体命令的实现)、Control(用于支持撤销功能)、ColorTV(接收者)、PatternRun(客户端)
4、2具体代码实现
AbstractCommand
ChangeChannelCommand
ColorTV
Control
TurnDownCommand
场景二
BlackWhiteTV
4、3运行结果
命令(AbstractCommand、ChangeChannelCommand、TurnDownCommand、TurnUpCommand)
接收者(ColorTV)
触发执行者(Control)
客户端(PatternRun)
A、支持取消(undo)和重做(redo)
A、抽象出待执行的动作以参数化某对象。
你可用过程语言中的回调(callback)函数表达这种参数化机制。
所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。
Command模式是回调机制的一个面向对象的替代品。
B、在不同的时刻指定、排列和执行请求。
一个Command对象可以有一个与初始请求无关的生存期。
如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
C、支持取消操作。
Command的Excute操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。
Command接口必须添加一个Unexecute操作,该操作取消上一次Execute调用的效果。
执行的命令被存储在一个历史列表中。
可通过向后和向前遍历这一列表并分别调用Unexecute和Execute来实现重数不限的“取消”和“重做”。
D、支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。
在Command接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。
从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用Execute操作重新执行它们。
E、用构建在原语操作上的高层操作构造一个系统。
这样一种结构在支持事务(transaction)的信息系统中很常见。
一个事务封装了对数据的一组变动。
Command模式提供了对事务进行建模的方法。
Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。
同时使用该模式也易于添加新事务以扩展系统。
基于设计模式的学习之旅-----状态模式
1、初识状态模式
按钮来控制一个电梯的状态,一个电梯开们,关门,停,运行。
每一种状态改变,都有可能要根据其他状态来更新处理。
例如,开门状体,你不能在运行的时候开门,而是在电梯定下后才能开门。
我们给一部手机打电话,就可能出现这几种情况:
用户开机,用户关机,用户欠费停机,用户消户,对方正在通话中,已经连接上对方等。
所以当我们拨打这个号码的时候:
系统就要判断,该用户是否在开机且不忙状态,又或者是关机,欠费等状态。
但不管是那种状态我们都应给出对应的处理操作。
2、什么是状态模式
允许一个对象在其内部状态改变时改变它的行为。
对象看起来似乎修改了它的类。
MobileContext、AbstractState、CallEndState、CallStartState、ConnectState、WaitState
非状态模式实现
/**
*电话
*
*@authorLuXiaoFeng
*@date2012-12-23
*/
publicclassMobileimplementsIStateConstants{
privateintcurrentState;
publicintgetCurrentState(){
returncurrentState;
}
publicvoidsetCurrentState(intcurrentState){
this.currentState=currentState;
publicbooleancallStart(){
booleanresult=false;
LogUtil.printWithSystemOut("
开始准备打电话,拨号中"
);
switch(currentState){
casecallend_state:
break;
casecallstart_state:
result=isBusy();
caseconnect_state:
casewait_state:
default:
returnresult;
publicvoidconnecting(intconnectState){
switch(connectState){
对方电话已经接通,正在聊天ing~"
聊天结束"
publicvoidcallEnd(intcallendState){
switch(callendState){
LogUtil.printWithSystemErr("
通话结束"
publicvoidwaitting(intwaitState){
switch(waitState){
对方正在通话中,请稍后再拨"
booleanisBusy(){
returntrue;
状态模式实现
MobileContext
AbstractState
CallEndState
CallStartState
ConnectState
WaitState
Context(环境,如MobileContext:
定义客户感兴趣的接口,维护State状态集合和当前状态)
State(状态,如AbstractState:
定义一个接口以封装与Context的一个特定状态相关的行为)
ConcreteState(状态子类,如ConnectState:
每一子类实现一个与Context的一个状态相关的行为)
A、它将与特定状态相关的行为局部化,并且将不同状态的行为分割开来
B、它使得状态转换显式化
C、State对象可被共享
D、状态模式的使用必然会增加系统类和对象的个数
E、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱
A、一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
B、一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
这个状态通常用一个或多个枚举常量表示。
通常,有多个操作包含这一相同的条件结构。
State模式将每一个条件分支放入一个独立的类中。
这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
8、与其他模式的区别
8.1责任链模式
职责链模式和状态模式都可以解决If分支语句过多,
从定义来看,状态模式是一个对象的内在状态发生改变(一个对象,相对比较稳定,处理完一个对象下一个对象的处理一般都已确定),
而职责链模式是多个对象之间的改变(多个对象之间的话,就会出现某个对象不存在的现在,就像我们举例的公司请假流程,经理可能不在公司情况),这也说明他们两个模式处理的情况不同。
这两个设计模式最大的区别就是状态模式是让各个状态对象自己知道其下一个处理的对象是谁。
而职责链模式中的各个对象并不指定其下一个处理的对象到底是谁,只有在客户端才设定。
用我们通俗的编程语言来说,就是
状态模式:
相当于Ifelseifelse;
设计路线:
各个State类的内部实现(相当于If,elseIf内的条件)
执行时通过State调用Context方法来执行。
职责链模式:
相当于Swichcase
客户设定,每个子类(case)的参数是下一个子类(case)。
使用时,向链的第一个子类的执行方法传递参数就可以。
就像对设计模式的总结,有的人采用的是状态模式,从头到尾,提前一定定义好下一个处理的对象是谁,而我采用的是职责链模式,随时都有可能调整链的顺序。
状态模式和策略模式的最大区别在于它有状态间的切换,一个状态完了,就要切换到它下一个状态。
8.2策略模式
状态模式和策略模式的实现方法非常类似,都是利用多态把一些操作分配到一组相关的简单的类中,因此很多人认为这两种模式实际上是相同的。
然而在现实世界中,策略(如促销一种商品的策略)和状态(如同一个按钮来控制一个电梯的状态,又如手机界面中一个按钮来控制手机)是两种完全不同的思想。
当我们对状态和策略进行建模时,这种差异会导致完全不同的问题。
例如,对状态进行建模时,状态迁移是一个核心内容;
然而,在选择策略时,迁移与此毫无关系。
另外,策略模式允许一个客户选择或提供一种策略,而这种思想在状态模式中完全没有。
一个策略是一个计划或方案,通过执行这个计划或方案,我们可以在给定的输入条件下达到一个特定的目标。
策略是一组方案,他们可以相互替换;
选择一个策略,获得策略的输出。
策略模式用于随不同外部环境采取不同行为的场合。
我们可以参考微软企业库底层ObjectBuilder的创建对象的strategy实现方式。
而状态模式不同,对一个状态特别重要的对象,通过状态机来建模一个对象的状态;
状态模式处理的核心问题是状态的迁移,因为在对象存在很多状态情况下,对各个businessflow,各个状态之间跳转和迁移过程都是及其复杂的。
例如一个工作流,审批一个文件,存在新建、提交、已修改、HR部门审批中、老板审批中、HR审批失败、老板审批失败等状态,涉及多个角色交互,涉及很多事件,这种情况下用状态模式(状态机)来建模更加合适;
把各个状态和相应的实现步骤封装成一组简单的继承自一个接口或抽象类的类,通过另外的一个Context来操作他们之间的自动状态变换,通过event来自动实现各个状态之间的跳转。
在整个生命周期中存在一个状态的迁移曲线,这个迁移曲线对客户是透明的。
我们可以参考微软最新的WWF状态机工作流实现思想。
在状态模式中,状态的变迁是由对象的内部条件决定,外界只需关心其接口,不必关心其状态对象的创建和转化;
而策略模式里,采取何种策略由外部条件(C)决定。
基于设计模式的学习之旅-----适配器模式
1、初始适配器模式
2、什么是适配器模式
将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
别名:
包装器Wrapper。
Adapter模式最关键的要求是:
Adapter是对两个功能相近的接口间的适配
类适配器使用多重继承对一个接口与另一个接口进行匹配,如下图所示:
对象匹配器依赖于对象组合,如下图所示:
Target:
ISpecialSwitchable
Client:
Adaptee:
IStandardSwitchable
Adapter:
SwitcherAdapter
Light
A、用一个具体的Adapter类对Adaptee和Target进行匹配。
B、使得Adapter可以重定义Adaptee的部分行为,因为Adapter是Adaptee的一个子类。
C、仅仅引入了一个对象,并不需要额外的指针以间接得到adaptee。
A、你想使用一个已经存在的类,而它的接口不符合你的需求。
B、你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
C、(仅适用于对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。
对象适配器可以适配它的父类接口。
基于设计模式的学习之旅-----中介者
1、初识中介者
那些年,我们一起上过的大学,班级里有班长,有团书记。
想一想如果没有QQ这种通讯工具的话,那么班长或者团支书该怎样下达消息呢?
?
同时,班级上两个同学之间也可惜沟通啊,沟通一下,院里哪个女生,哪个帅哥呀~~~如果没有QQ的话,大概就是下面的情景:
哎呀呀,看看这个乱那。
如果同学的数目多起来就会变成网状的结构啦。
原本把一个系统分割成一些对象是可以增强复用性的,但是现在的情况是,这些兑现之间存在着大量的联系,耦合性极高。
这是很不利于复用的,同时这种情况使得系统的灵活性大大的降低,使得对系统的扩展很难,要是新转来一个学生的话,要改动的地方就多了去了。
如果现在可以使用QQ,那么可以采用另一种方式设计这个系统呢,比如做成星形的结构:
看看这种“星形结构”和“网状结构”的区别吧,显然采用星形结构就可以避免上面的网状结构存在的问题了,实际上这里的QQ就是指的是中介,这样一来每个学生对象就不用存在耦合了,同学之间需要交流可以通过一个QQ群。
2、什么是中介者
用一个中介对象来封装一系列的对象交互。
中介者使各对象不需要显式地相互引用,从
而使其耦合松散,而且可以独立地改变它们之间的交互。
新年快到了,公司要给每位员工送年货。
当然,公司不可能直接消耗人力资源自己往每个员工家里送物品,所以收集了每个员工的一些信息,通过快递公司为其送出物品。
ExpressMediator(抽象的中介者)、EMSExpressMediator(具体的中介者EMS快递)、Colleage(抽象的同事类)、Company(具体的同事类公司)、Person(具体的同事类员工)
ExpressMediator(抽象的中介者)
EMSExpressMediator(具体的中介者EMS快递)
C
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 设计 模式 学习