十三 每天学习一个设计模式:行为型之责任链模式( 三 )


●异常情况欠考虑
妻子只能向丈夫请示吗?如果妻子(比如一个现代女性穿越到古代了,不懂什么“三从四德”)向自己的父亲请示了,父亲应该做何处理?我们的程序上可没有体现出来,逻辑失败了!
既然有这么多的问题,那我们要想办法来解决这些问题,我们先来分析一下需求,女性提出一个请示,必然要获得一个答复,甭管是同意还是不同意,总之是要一个答复的,而且这个答复是唯一的,不能说是父亲作出一个决断,而丈夫也作出了一个决断,也即是请示传递出去,必然有一个唯一的处理人给出唯一的答复,OK,分析完毕,收工,重新设计,我们可以抽象成这样一个结构,女性的请求先发送到父亲类,父亲类一看是自己要处理的,就作出回应处理,如果女儿已经出嫁了,那就要把这个请求转发到女婿来处理,那女婿一旦去天国报道了,那就由儿子来处理这个请求,类似于如图所示的顺序处理图 。
父亲、丈夫、儿子每个节点有两个选择:要么承担责任,做出回应;要么把请求转发到后序环节 。结构分析得已经很清楚了,那我们看怎么来实现这个功能,类图重新修正,如图所示 。
从类图上看,三个实现类、、Son只要实现构造函数和父类中的抽象方法就可以了,具体由谁处理女性提出的请求,都已经转移到了抽象类中,我们来看怎么实现. 。
public abstract class Handler {public final static int REQUEST_FATHER = 1;public final static int REQUEST_HUSBAND = 2;public final static int REQUEST_SON = 3;/*** 能处理的级别*/private int level = 0;/*** 责任传递,下一个人责任人是谁*/private Handler nextHandler;/*** 每个类都要说明一下自己能处理哪些请求** @param level*/public Handler(int level) {this.level = level;}/*** 一个女性要求逛街,你要处理这个请求** @param women*/public final void handleMessage(IWomen women) {if (women.getType() == this.level) {this.response(women);} else {if (this.nextHandler != null) {//有后续环节,才把请求往后递送this.nextHandler.handleMessage(women);} else {System.out.println("---没地方请示了,按不同意处理---");}}}/*** 如果不属于你处理的请求,你应该让她找下一个环节的人,如果女儿出嫁了,* 还向父亲请示是否可以逛街,那父亲就应该告诉女儿,应该找丈夫请示* @param handler*/public void setNext(Handler handler) {this.nextHandler = handler;}/*** 有请示那当然要回应* @param women*/protected abstract void response(IWomen women);}
方法比较长,但是还是比较简单的,读者有没有看到,其实在这里也用到模板方法模式,在模板方法中判断请求的级别和当前能够处理的级别,如果相同则调用基本方法,做出反馈;如果不相等,则传递到下一个环节,由下一环节做出回应,如果已经达到环节结尾,则直接做不同意处理 。基本方法需要各个实现类实现,每个实现类只要实现两个职责:一是定义自己能够处理的等级级别;二是对请求做出回应,我们首先来看首节点类 。
public class Father extends Handler {/*** 父亲只处理女儿的请求*/public Father() {super(Handler.REQUEST_FATHER);}@Overrideprotected void response(IWomen women) {System.out.println("--------女儿向父亲请示--------");System.out.println(women.getRequest());System.out.println("父亲的答复是:同意");}}
丈夫类定义自己能处理的等级为2的请示 。
public class Husband extends Handler {/*** 丈夫只处理妻子的请求*/public Husband() {super(Handler.REQUEST_HUSBAND);}@Overrideprotected void response(IWomen women) {System.out.println("--------妻子向丈夫请示--------");System.out.println(women.getRequest());System.out.println("丈夫的答复是:同意");}}