行为模式

来源:互联网 发布:乐视网络机顶盒好吗 编辑:程序博客网 时间:2024/04/28 08:30

策略模式

意图

Ø         定义一系列算法,把他们一个个封装起来,并且使他们可相互替换。

适用

Ø          

体现的设计原则

Ø         开闭原则

技术

Ø         委托:环境类委托行为类实现行为

Ø         继承:提供多态

 

区别联系

Ø         和代理模式区别:策略模式的环境类需要告诉行为类现在的环境,具体使用哪个行为,而代理类只是代理。

推演

Ø         把所有业务都放到客户段,这样客户段通过分支语句选择具体实现那个算法

Ø         客户段在子类中实现不同行为,但这样环境和行为是强耦合的

Ø         使用策略模式,策略模式把环境和行为分开。

总结

 

 

 

模板模式

意图

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中

适用

 

体现的设计原则

Ø         好莱坞原则(多态)

Ø          

技术

Ø         继承:可以复用代码,算法只存在在一个地方,容易修改

区别联系

Ø         和策略模式区别:没有环境类,提供了算法框架(一组行为);通过多态选择算法,但是策略模式是通过对象组合方式选择算法。

 

推演

 

总结

Ø         使用钩子

 

 

观察者模式

 

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

适用

 

体现的设计原则

 

技术

 

区别联系

Ø         观察者模式是处理两个方法之间的调用关系,而装饰模式一样是处理两个方法之间调用关系,但是他们方法之间关系不一样。一个是包装,一个是通知.

推演

Ø         一个处警系统。可以接收烟雾、红外信息,然后显示是哪里出现上述信息,并且发出警报,如在系统界面闪烁,喇叭响

根据以往面向过程编程经验

Class 系统{

       接收信息(){}

       界面闪烁(){}

       喇叭响(){}

       检查接收信息(){检查到,则调用界面闪烁和喇叭响}

}

Class Client{

       系统。接收信息()

       系统。检查接收信息()

}

 

这样的程序结构显然不满增加新的提醒装置,而不修改程序。经过改造如下

 

Abstract public Class 系统{

       接收到信息(){}

}

Public class 接收烟雾系统 extends 系统{

       接收到烟雾(){}

}

Public interface 观察{

       Void update();

}

Class 观察闪烁{

       界面闪烁(){}

       Public void update(){

              界面闪烁();

       }

}

Class 观察喇叭{

       喇叭响(){}

       Public void update(){

              喇叭响();

       }

}

到目前为止,我们的结构已经满足两个变化的因素分离,即接收信息和接收到信息后的处理方式。但行为之间的依赖关系没有体现在模式中,他们之间的依赖关系是,如果接收到烟雾信息就要通知观察者让他们执行相应动作。这就要求主题层要拥有具体观察者的集合,当事件发生时就从集合中调出对象,执行接口方法

总结

Ø         依赖关系固定时,增加观察者模式只能使问题复杂

Ø         如果需要过滤多余的通知可以使用策略模式

Ø         主体抽象层应该是类而不能是接口,因为主体抽象层包含了公共方法

Ø         具体观察者应该有相同类型和接口

Ø         这个模式一个是分离变化,另外则是封装依赖关系

 

职责链模式

 

意图

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系

适用

有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定

你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求

可处理一个请求的对象集合应被动态指定

体现的设计原则

技术

区别联系

和观察者模式比较:他们中都存在根据一个消息进行后续处理。但是他们处理方式不一样,一个是所有的都参与处理,另一个是传递处理请求。

推演

假如有一个电话接警系统,如果用户打110则转到公安局,119则转到消防局,120则转到医院

Class 电话处理{

       电话处理(号码){

       If 号码=110{转到公安局}

       If 号码=119{转到消防局}

       If 号码=120{转到医院}

       }

}

这样的处理方式显然不满足再增加处理者。所以如下改造

Class 电话处理{

       电话号码

}

Class 公安处理{}

Class 消防处理{}

Class 医院处理{}

 

这样处理可以新增处理方式,但是具体使用哪个处理方式的问题没有解决,

总结

Ø         请求的发送者和接收者解耦

Ø         职责连的建立不是职责连模式完成

Ø         请求的发送者不是职责连

Ø         具体处理者接到请求后可以选择将请求处理掉或将请求传递给下家纯责任链:责任链中的对象只能 从两个行为中选择一个,一是承担责任,二是把责任推给下家。不允许出现责任链中的对象承担了一部分责任后又将责任推给下家。在一个纯的责任链中请求必须被 某一个对象所处理。不允许出现请求不被任何对象处理的情况

Ø          

 

命令模式

意图

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或者记录请求日至,以及支持可撤销的操作

适用

 

体现的设计原则

解耦:

组合:

技术

继承:实现多态,可以是多种命令

委托:

区别联系

观察者模式是要实现两个命令之间的依赖关系,相同点是有两个方法

职责连是封装处理方法,使得处理方法能够按照处理连对消息处理,该模式的消息发送者不在模式之内,而且建立处理连也不在之内

处理两个方法,这两个方法之间通过一个命令关联,所以通过命令解耦。

推演

Ø         去饭店吃饭这一场景很符合命令模式。如果我们去路边大排档吃饭很简单,直接告诉师傅烧什么菜就可以了(大排档一般也只有师傅),但是如果我们到正规饭店吃饭,则不一样,首先服务员会引导我们入席,然后点菜,服务员会告诉厨师根据单子烧菜。

Ø         第一种情况和第二种情况比多了服务员和菜单,多了服务员厨师可以减少和客户的沟通,增加了菜单则可以适应菜单变化,否则厨师需要自己管理菜单。

Ø         服务员、菜单、厨师三者关系看:服务员通过菜单实现和厨师的解耦,服务员和厨师不需要直接交流;他们之间的调用关系是:服务员持有菜单的引用,服务员调用菜单方法,菜单把这个调用再委托给厨师

Ø         服务员、菜单、厨师对于客户都是不透明的

 

 

总结

Ø         耦合是软件不能抵御变化灾难的根本性原因。不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系

Ø         在软件构建过程中,行为请求者行为实现者通常呈现一种紧耦合。但在某些场合——比如需要对行为进行记录、撤销/重做 undo/redo)、事务等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将行为请求者行为实现者解耦?将一组行为抽象 为对象,可以实现二者之间的松耦合

 

迭代子模式

意图

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

适用

 

体现的设计原则

开闭原则

技术

继承

委托

区别联系

迭代模式和上面几个模式区别很大。这个模式是解决对对象的访问

推演

一个聚合对象包含很多其他不同类型的对象,如果我们要从中搜寻对象,我们把搜寻对象的方法和被搜寻的聚合对象分离出来,这样能够满足开闭原则

总结

访问模式

意图

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作

适用

一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作

需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作污染这些对象的类

定义对象结构的类很少改变,但是经常需要在此结构上定义新的操作。

体现的设计原则

 

技术

 

区别联系

 

推演

可以这样假设一个场景:在动物园有三个动物,猴子、狗熊、海狮,当他们看到一个皮球,猴子可能是推、狗熊可能是拍、海狮可能是顶。则如下构造程序

Class 猴子{

       皮球。推();

}

Class 狗熊{皮球。拍();}

Class 海狮{皮球。顶();}

Class 皮球{推();拍();顶();}

这样属于传统构造程序方法,这样有个问题,假如现在增加访问者,会对原来程序产生不良影响。譬如增加一个人,人可能是踢皮球,这时皮球类需要修改。如果要避免上述问题,需要把具体的皮球动作放到访问者中,而是让所有访问者有一个公共接口

 

Interface 访问者{void visit(皮球)}

Class 狗熊 implements访问者{

       Public void visit(皮球){

              拍(皮球);

       }

       Public void 拍(皮球){}

}

 

Class 皮球{

       Visitor

       Public void accept(Visitor visitor){

              visistor.visit(this);

       }

}

这样他们之间形成了一个相互委托,皮球把对皮球的动作委托给访问者,而访问者引用皮球只是为了得到皮球的信息

 

 

总结

因为对对象的操作和访问者本身有关,所以把这个操作放到访问者中去,这样避免访问者变化导致问题

 

状态模式

意图

允许一个对象在其内部状态改变时改变它的行为。

适用

一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变行为

一个操作中含有庞大的多分支的条件语句,并且这些分支依赖于该对象的状态

体现的设计原则

技术

区别联系

推演

曾经做个一个电话语音卡程序,处理电话业务。

Switch 来电电信号

       Case 信号为1

       Case 信号为2

       。。。

这样处理,存在问题不要多说。电话语音处理系统是根据不同电话电信号,进行不同处理。这里面包括两个方法改变状态,处理事件

 

总结

 

原创粉丝点击