1、责任链模式定义如下:
使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
2、代码示例
/** * 女性接口 */ public interface IWomen { //获得个人状况 public int getType(); //获得个人请示, 你要干什么? 出去逛街? 约会?还是看电影? public String getRequest(); }
/** * 古代妇女 */ public class Women implements IWomen { /* * 通过一个int类型的参数来描述妇女的个人状况 * 1--未出嫁 * 2--出嫁 * 3--夫死 */ private int type=0; //妇女的请示 private String 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; } } //获得自己的状况 public int getType(){ return this.type; } //获得妇女的请求 public String getRequest(){ return this.request; } }
/** * 抽象处理类 */ 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; } //一个女性( 女儿、 妻子或者是母亲) 要求逛街, 你要处理这个请求 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("---没地方请示了, 按不同意处理--- "); } } } /** 如果不属于你处理的请求, 你应该让她找下一个环节的人, 如女儿出嫁了, * 还向父亲请示是否可以逛街, 那父亲就应该告诉女儿, 应该找丈夫请示 */ public void setNext(Handler _handler){ this.nextHandler = _handler; } //有请示那当然要回应 protected abstract void response(IWomen women); }
/** * 一是定义自己能够处理的等级级别; 二是对请求做出回应, * 父亲类 */ public class Father extends Handler { //父亲只处理女儿的请求 public Father() { super(Handler.FATHER_LEVEL_REQUEST); } //父亲的答复 @Override protected void response(IWomen women) { System.out.println("--------女儿向父亲请示-------"); System.out.println(women.getRequest()); System.out.println("父亲的答复是:同意 "); } }
//丈夫类 public class Husband extends Handler { //丈夫只处理妻子的请求 public Husband(){ super(Handler.HUSBAND_LEVEL_REQUEST); } //丈夫请示的答复 protected void response(IWomen women) { System.out.println("--------妻子向丈夫请示-------"); System.out.println(women.getRequest()); System.out.println("丈夫的答复是: 同意 "); } }
//儿子类 public class Son extends Handler { //儿子只处理母亲的请求 public Son(){ super(Handler.SON_LEVEL_REQUEST); } //儿子的答复 protected void response(IWomen women) { System.out.println("--------母亲向儿子请示-------"); System.out.println(women.getRequest()); System.out.println("儿子的答复是: 同意 "); } }
//场景类 public class Client { public static void main(String[] args) { //随机挑选几个女性 Random rand = new Random(); ArrayList<IWomen> arrayList = new ArrayList(); for(int i=0;i<5;i++){ arrayList.add(new Women(rand.nextInt(4),"我要出去逛街")); } //定义三个请示对象 Handler father = new Father(); Handler husband = new Husband(); Handler son = new Son(); //设置请示顺序 father.setNext(husband); husband.setNext(son); for(IWomen women:arrayList){ father.HandleMessage(women); } } }
3、优点:将请求和处理分开,请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌。
缺点:
责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题。
二是调试不很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
4、注意事项:
链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免
无意识地破坏系统性能。