转载请注明出处!!!http://blog.csdn.net/zhonghuan1992
所有配套代码均在github上:https://github.com/ZHONGHuanGit/DesignPattern
跟着ZHONGHuan学习设计模式
责任链模式
根据GOF95,责任链模式是一种对象的行为模式。
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链,请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
我觉得看了前面的设计模式之后,对于责任链,要理解起来不难。不过我们依然从例子入手。不知道大家有没有玩过击鼓传花,就是一堆人坐一圈,然后一个标志物,假设是花吧这儿,然后有一个击鼓的人,他背对所有人,开始敲鼓,花在几个人中传着,当鼓声停了。花停谁那儿,谁就要表演节目。
这个游戏可以算是很形象的展示了一下责任链。下面看一下责任链模式的结构。
模式结构:
责任链模式涉及到的角色如下所示:
抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
介绍完结构,最好的方式还是讲简单的实现代码给出来,下面看一下简单的实现代码,代码中有注释。
abstract class Handler { //抽象处理者(Handler)角色
protected Handler successor;//这里是传递给后继的对象
public abstract void handleRequest(); //处理请求的抽象方法,形式并不一定要这样
//getter和setter
public Handler getSuccessor() {
return successor;
}
public voidsetSuccessor(Handler successor) {
this.successor = successor;
}
}
class ConcreteHandler extends Handler { //具体处理者(ConcreteHandler)角色:
//具体的处理方法
public void handleRequest(){
if(getSuccessor() == null)//判断是否有后继的责任对象,没有则自己处理,有则传出去。
{
System.out.println("让我来接着吧");
}else
{
System.out.println("交给下人办吧");
getSuccessor().handleRequest();
}
}
}
public class Client {
public static void main(String[] args) {
Handler h1 = new ConcreteHandler();
Handler h2 = new ConcreteHandler();
Handler h3 = new ConcreteHandler();
h1.setSuccessor(h2);
h2.setSuccessor(h3);
h1.handleRequest();
}
}
由于本示例的传递逻辑非常简单:只要有下家,就传给下家处理;如果没有下家,就自行处理。
我想现在,应该明白了责任链是怎么一回事了。我们再扩展一下。
纯的与不纯的责任链模式
一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又 把责任向下传的情况。
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。
纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。有些人认为不纯的责任链根本不是责任链模式,这也许是有道理的。但是在实际的系统里,纯的责任链很难找到。如果坚持责任链不纯便不是责任链模式,那么责任链模式便不会有太大意义了。
上面的代码例子是纯的责任链,那么什么是不纯的责任链呢?
我们先想象一下这样的场景,打仗。大元帅发出命令,今晚偷袭敌营,大元帅发出命令,令将军甲偷袭敌军营。这是大元帅发出的命令,但是大元帅只是让它偷袭,其它任务没说。那么将军甲当然是接收这个命令,自己琢磨一下,手下副将乙领兵前往。副将乙接着这个指令,叫上一个营长丙,让他带上所有兵马跟着他晚上偷袭。营长丙叫上小弟们。…..这个责任链是不纯的,每个人都对责任进行处理了。实现代码就暂时不写了,不难,可以自己实现下。
责任链的优缺点:
优点:责任链的请求是一开始就穿进去了,处理却是经过了一个链,它将请求和处理就这样分开了,请求方不用知道是谁请求了,反正有人处理。这样增加了灵活性。
缺点:性能问题是责任链的缺点,链表的处理向来都是比较费时的,从链头到链尾。