您的位置:首页 > 其它

设计模式之行为类模式大PK

2016-12-12 08:59 218 查看
行为类模式大PK
行为类模式包括责任链模式命令模式、解释器模式、迭代器模式、中介者模式备忘录模式观察者模式状态模式策略模式模板方法模式访问者模式。该组设计模式众多,如下我们着重介绍一下命令模式VS策略模式、状态模式VS策略模式、观察者模式VS责任链模式。

命令模式VS策略模式
命令模式和策略模式类图很相似,只是命令模式多了一个接收者(Receiver)角色,通过确切的Command类调用Receiver类,实现了调用者和具体的接收者的解耦。策略模式的意图是封装算法,它认为“算法”已经是一个完整的、不可拆分的原子业务,通过对算法的封装实现算法的独立,并且可以相互转换,让行为的变化独立于拥有行为的客户,如我们在策略模式中的例子:诸葛亮给赵云的锦囊妙计,其中每个计策就是一个算法,对妙计进行封装,在不同的时间调用执行不同的计策;而命令模式是对动作解耦,把一个动作的执行分为执行对象(Receiver)和执行行为(Command),让两者相互独立而不相互影响,我们在命令模式中举出了软件开发的例子,软件开发中包括美工组、界面组、编码组,这就是各个执行对象,还包括一个产品经理,就是那个执行行为,客户通过只跟Command打交道实现各个执行对象的行为。

  接下来我们从对文件压缩的业务需求出发,分别按照命令模式和策略模式设计出一套实现,来看看他们侧重点的不同。文件的压缩其中有两种格式zip和gzip,他们是两种不同的压缩格式,我们将分别实现不同格式的压缩和解压缩功能。

命令模式实现对文件的压缩和解压缩

  命令模式的主旨是封装命令,使请求者和实现者解耦。我们先看看命令模式实现文件压缩和解压缩的类图:

public class Human {
//人生有三种状态童年、成年和老年
public static HumanState childState = new ChildrenState();
public static HumanState adultState = new AdultState();
public static HumanState oldState = new OldState();
public HumanState state = null;
public void setHumanState(HumanState state){
this.state = state;
this.state.setHuman(this);
}
public void work(){
this.state.work();
}
}

public abstract class HumanState {
protected static Human human = null;
public void setHuman(Human human){
this.human = human;
}
public abstract void work();
}

public class ChildrenState extends HumanState{

@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("童年是最无忧无虑的,在家的港湾的庇护下快乐的成长");
//切换到下一个人生状态
super.human.setHumanState(Human.adultState);
}

}

public class AdultState extends HumanState{

@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("成为了社会的中坚力量,有了自己的家庭和事业");
super.human.setHumanState(Human.oldState);
}

}

public class OldState extends HumanState{

@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("一路上收藏点点滴滴的微笑,坐着摇椅和心爱的人慢慢聊");
}

}

public class Client {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Human human = new Human();
human.setHumanState(new ChildrenState());
human.work();     //有状态切换在ChildrenState的work()
human.work();
human.work();
}

}


View Code

总结

从上人生的例子中可以看出,状态模式侧重的是人的生长规律,而策略模式侧重的是人的工作逻辑,不同的人生阶段工作不同。

环境角色的职责不同:两者都有一个叫Context环境角色的类,但是两者的区别很大,策略模式的环境角色只是一个委托作用,负责算法的替换;而状态模式的环境角色不仅仅是委托行为,它还具有登记状态变化的功能,与具体的状态类协作,共同完成状态切换行为随之切换的任务。

解决问题的重点不同:策略模式旨在解决内部算法如何改变的问题,也就是将内部算法的改变对外界的影响降低到最小,保证算法之间的自由切换;而状态模式旨在改变内部状态的改变而引起的行为的改变的问题,出发点是事务的状态,状态封装而暴露行为,一个对象状态的改变,从外界来看就好像是行为改变。

解决问题的方法不同:策略模式解决算法自由切换,但是什么时候用什么算法它决定不了,而装填模式对外暴露行为,状态的变换一般是由环境角色和具体状态共同完成的,也就是说装填模式封装了状态变化而暴露了不同的行为或行为结果。

应用场景不同:策略模式是算法的封装,可以是一个有意义的对象,也可以是一个无意义的逻辑片段,如MD5加密算法,算法必须是平行的;状态模式则要求有一系列状态发生变化的场景,他要求的是有状态且有行为的场景,也就是一个对象必须有二维(状态和行为)描述才能采用状态模式。

复杂度不同:策略模式结构比较简单,容易扩展,而状态模式通常比较复杂,因为他要从两个角色看到一个对象状态和行为的改变,也就是说封装的是变化。

观察者模式VS责任链模式
  观察者模式中也存在触发链啊,想想当每一个被观察者有动作时,就会触发被观察者的相应动作,这也叫做观察者链,这与责任链非常相似,都实现了事务的链条化处理,观察者模式中允许传递的事件发生改变,而责任链模式中一般事件的结构传递不发生变化。如你在上课睡觉,打鼾声太大,盖过了老师讲课的声音,所以老师发火了,老师已经处理不了了,然后将你上课打鼾这件事报告给了年级主任,然而年级主任也处理不了,报告给了你的老爸,然后老爸知道你上课睡觉这件事,你的麻烦就大了,在这一系列的事件的处理中,打鼾事件时不变的;当然了老师针对你打鼾这件事没有报告给年级主任,而是老师在收到你打鼾这件事后,老师掏出了扩音器,盖过了你打鼾的声音,其他同学的耳朵就得遭殃了,老师是观察者,观察你是否睡觉打鼾,而一旦收到你打鼾,就用扩音器,同时老师也是一个被观察者,其他同学听老师讲课,老师一旦用扩音器,其他同学耳朵遭殃,在这一系列事件中,首先的事件时你上课打鼾,然后是老师用扩音器讲课。这就是观察者模式中的触发链模式。

小结

通过如上例子,我们发现触发链和责任链虽然都是链结构,但是还是有区别的。

链中的消息对象不同:责任链模式中消息在链中传递时,消息的结构基本不会改变,而观察者模式中消息可以自由改变,只要上下级节点对传递对象了解即可,观察者模式只要求联众相邻两个结点的消息对象固定。

上下节点的关系不同:在责任链模式中,上下节点没有关系,都是接收同样的对象,所有传递的对象都是从链首传递过来;而观察者模式的上下节点关系密切,链中任意两个相邻接点都是一个牢固的独立团体。

消息的分销渠道不同:在责任链模式中,消息从链首向链尾沿着单一固定的方向传递;而观察者模式则不同,消息的传递灵活性较大,一个消息具体怎传递时不固定的,可以以广播方式传递,也可以以跳跃方式传递,这取决于处理消息的逻辑。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: