中国古代对妇女制定了“三从四德”的道德规范,“三从”是指未嫁从父,既嫁从夫,夫死从子。也就是说一位女性在结婚之前要听从父亲,结婚后要听从于丈夫,如果丈夫死了还要听从于儿子。比如要逛街,作为父亲,丈夫或儿子,只有两种选择:要不要承担起责任来,允许她或不允许她逛街;要不就让她请示下一个人。这就延伸出了责任链模式。类图如下:
上面处理请求有三个实现类,Father,Husband,Son只要实现构造函数和父类中的抽象方法response方法就可以了,具体由谁处理女性提出的请求,都已转移到了Handler抽象类中。
女性接口代码如下:
package com.jack.responsibilitychain;
/**
* Created by jack on 2017/8/7.
* 女性接口
*/
public interface IWomen {
/**
*获得个人状况,通过返回值确定结婚与否,丈夫是否去世
* @return
*/
public int getType();
/**
*获得个人请示,出去逛街还是吃饭
* @return
*/
public String getRequest();
}
女性实现类代码如下:
package com.jack.responsibilitychain;/** * Created by jack on 2017/8/7. * 女性类 */public class Women implements IWomen{ /** * 通过参数来描述妇女的个人状况 * 1---未出嫁 * 2---出嫁 * 3---夫死 */ private int type; /** * 妇女的请示 */ private String request = ""; /** * 构造函数传递过来请求 * @param type * @param request */ public Women(int type, String request) { this.type = type; switch (this.type){ case 1: this.request = "女儿的请求是:"+request; break; case 2: this.request = "妻子的请求是:"+request; break; case 3: this.request = "母亲的请求是:"+request; break; } } /** * 获得妇女的个人状况 * @return */ @Override public int getType() { return this.type; } /** * 获得妇女的请求 * @return */ @Override public String getRequest() { return this.request; }}
下面我们看看Handler怎么实现,代码如下:
package com.jack.responsibilitychain;/** * Created by jack on 2017/8/7. * 处理抽象类 */public abstract class Handler { /** * 定义常量 */ public final static int FATHER_LEVEL_REQUEST = 1; public final static int HUSBAND_LEVEL_REQUEST = 2; public final static int SON_LEVEL_REQUEST = 3; /** * 能处理的级别 */ private int level = 0; /** * 责任传递,下一个人责任人是谁 */ private Handler nextHandler; public Handler(int level) { this.level = level; } /** * 一个女性要求逛街或吃饭,你需要处理这个请求 * @param women */ public final void HandleMessage(IWomen women){ if (this.level == women.getType()) { this.response(women); }else { //有后续环节才把请求往后传递 if (this.nextHandler != null) { this.nextHandler.HandleMessage(women); }else {//已经没有后续处理人了,不用处理了 System.out.println("--没地方请示了,按不同意处理\n--"); } } } /** * 如果不属于你处理的请求,你应该让她找下一个环节的人,如果女儿出嫁了, * 还向父亲请示能否逛街,那父亲应该告诉女儿,应该找丈夫请示 * @param handler */ public void setNext(Handler handler){ this.nextHandler = handler; } /** * 有请示还需要回应,该方法就是表示回应 * @param women */ public abstract void response(IWomen women);}
上面使用到了模板方法模式,在模板方法中判断请求的级别和当前能够处理的级别,如果相同则调用基本方法,做出反馈;如果不相等,则传递到下一个环节,有下一个环节做出回应,如果已经达到环节结尾,则直接做不同处理。基本方法response需要各个实现类实现,每个实现类只要实现两个职责:一是定义自己能够处理的级别;二是对请求做出回应。
父亲类代码:
package com.jack.responsibilitychain;/** * Created by jack on 2017/8/7.、 * 父亲类 */public class Father extends Handler{ /** * 父亲只处理女儿的请求 */ public Father() { super(Handler.FATHER_LEVEL_REQUEST); } /** * 父亲的答复 * @param women */ @Override public void response(IWomen women) { System.out.println("---------女儿向父亲请示----------"); System.out.println(women.getRequest()); System.out.println("父亲的答复是:同意\n"); }}
丈夫类:
package com.jack.responsibilitychain;/** * Created by jack on 2017/8/7. * 丈夫类 */public class Husband extends Handler{ /** * 丈夫只处理妻子的请求 */ public Husband() { super(Handler.HUSBAND_LEVEL_REQUEST); } /** * 丈夫请示的答复 * @param women */ @Override public void response(IWomen women) { System.out.println("---------妻子向丈夫请示----------"); System.out.println(women.getRequest()); System.out.println("丈夫的答复是:同意\n"); }}
儿子类:
package com.jack.responsibilitychain;/** * Created by jack on 2017/8/7. * 儿子类 */public class Son extends Handler{ /** * 儿子只处理母亲的请求 */ public Son() { super(Handler.SON_LEVEL_REQUEST); } /** * 儿子的答复 * @param women */ @Override public void response(IWomen women) { System.out.println("---------母亲向儿子请示----------"); System.out.println(women.getRequest()); System.out.println("儿子的答复是:同意\n"); }}
测试代码如下:
package com.jack.responsibilitychain;import java.util.ArrayList;import java.util.Random;/** * Created by jack on 2017/8/7. */public class MainTest7 { public static void main(String[] args) throws CloneNotSupportedException { //随机挑选几个女性 Random random = new Random(); ArrayList<IWomen> womenList = new ArrayList<>(); for (int i=0;i<5;i++){ womenList.add(new Women(random.nextInt(4), "我要出去逛街")); } //定义三个请示对象 Father father = new Father(); Husband husband = new Husband(); Son son = new Son(); //设置请示顺序 father.setNext(husband); husband.setNext(son); for (IWomen women: womenList) { father.HandleMessage(women); } }}
测试可能的一种输出如下:
--没地方请示了,按不同意处理----没地方请示了,按不同意处理----没地方请示了,按不同意处理-----------女儿向父亲请示----------女儿的请求是:我要出去逛街父亲的答复是:同意---------妻子向丈夫请示----------妻子的请求是:我要出去逛街丈夫的答复是:同意
责任链模式的定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
责任链模式的重点是在链上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果,其通用类图如下:
优点:
责任链模式非常明显的优点是将请求和处理分开。请求者可以不用知道谁处理的,处理者可以不用知道请求的全貌,两者解耦,提供系统的灵活性。
缺点:
责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链同遍历到链尾,特别是在链比较长的时候,性能时一个非常大的问题。二是调试不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。