设计模式之禅——责任链模式

责任链模式的定义:
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

例子:古代女子要 “三从四德”,这里的三从是什么呢,是指“未嫁从父,既嫁从夫,夫死从子”。也就是说,一位女性在结婚前听父亲的,结婚后听丈夫的,丈夫G了听儿子的,没有儿子听小叔子的XXX。

需求很简单:通过程序描述一下古代妇女的“三从制度”。我们来看类图

设计模式之禅——责任链模式_第1张图片

见代码:

/**
*女性接口仅两个方法,一个是获得当前的个人状况,通过返回值决定是结婚了还*是没结婚、丈夫是否在世等,另一个方法是要请示的内容,要出去逛街还是吃饭
*/
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;
       this.request = _request;
   }
   public int getType(){
       return type;
   }

    @Override
    public String getRequest() {
        return null;
    }
}
//掌权者的接口
public interface IHandler {
    //一个女性要求逛街,你要处理这个请求
    public void HandlerMessage(IWomen women);
}
public class Father implements IHandler {

    @Override
    public void HandlerMessage(IWomen women) {
        System.out.println("女儿的请示是:" + women.getRequest());
        System.out.println("父亲的答复是:同意");
    }
}
public class Husband implements IHandler {
    @Override
    public void HandlerMessage(IWomen women) {
        System.out.println("妻子的请示是:" + women.getRequest());
        System.out.println("丈夫的答复是:同意");
    }
}
public class Son implements IHandler {
    @Override
    public void HandlerMessage(IWomen women) {
        System.out.println("母亲的请示是:" + women.getRequest());
        System.out.println("儿子的答复是:同意");
    }
}
public class Client {
    public static void main(String[] args) {
        Random random = new Random();
        ArrayList arrayList = new ArrayList<>();
        for(int i = 0; i < 5; ++i){
            arrayList.add(new Women(random.nextInt(4), "宝宝中秋要去逛街"));
        }
        IHandler father = new Father();
        IHandler husband = new Husband();
        IHandler son = new Son();
        for(IWomen women:arrayList){
            if(women.getType() == 1){
                System.out.println("------------女儿向父亲请示------------");
                father.HandlerMessage(women);
            }else if(women.getType() == 2){
                System.out.println("------------妻子向丈夫请示------------");
                husband.HandlerMessage(women);
            }else  if(women.getType() == 3){
                System.out.println("------------母亲向儿子请示------------");
                son.HandlerMessage(women);
            }else{
                //暂时先老实待着
            }
        }
    }
}
/*Output
------------母亲向儿子请示------------
母亲的请示是:宝宝中秋要去逛街
儿子的答复是:同意
------------女儿向父亲请示------------
女儿的请示是:宝宝中秋要去逛街
父亲的答复是:同意
------------妻子向丈夫请示------------
妻子的请示是:宝宝中秋要去逛街
丈夫的答复是:同意
------------女儿向父亲请示------------
女儿的请示是:宝宝中秋要去逛街
父亲的答复是:同意
------------妻子向丈夫请示------------
妻子的请示是:宝宝中秋要去逛街
丈夫的答复是:同意
*/

好的,上面的代码已经简单的实现了”三从制度“,但是它有以下明显的缺点

1、职责限定不清楚
对女儿的请示,应该在父亲类中做出决定,父亲有责任、有义务处理女儿的请示,因此Father类应该是知道女儿的请求由自己来处理,而不是在Client类中组装出来,也就是说原本应该是父亲这个类做的事情抛给了其他类进行处理——不应该是这样的。

2、代码臃肿
if … else ,我们不是经常讽刺这样的代码吗。

3、耦合过重
想象一下,如果IHandler的实现类继续拓展怎么办?修改Client类?我们是要尽量遵守开闭原则的呀!

4、异常情况欠考虑
一个妻子如果在请示了自己的父亲怎么办?

ok,带着这些问题,我们重新设计类图

设计模式之禅——责任链模式_第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 type;
   }

    @Override
    public String getRequest() {
        return request;
    }
}
public abstract class IHandler {
    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 IHandler nextHandler;
    public IHandler(int _level){
        this.level = _level;
    }
    public final void HandlerMessage(IWomen women){
        if(women.getType() == this.level){
            this.response(women);
        }else{
            if(this.nextHandler != null){
                this.nextHandler.HandlerMessage(women);
            }
        }
    }
    protected abstract void response(IWomen women);
    public void setNext(IHandler _handler){
        this.nextHandler = _handler;
    }
}
public class Father extends IHandler{


    public Father(){
        super(IHandler.FATHER_LEVEL_REQUEST);
    }
    @Override
    protected void response(IWomen women) {
        System.out.println("------------女儿向父亲请示------------");
        System.out.println("女儿的请示是:" + women.getRequest());
        System.out.println("父亲的答复是:同意");
    }
}
public class Husband extends IHandler {


    public Husband() {
        super(IHandler.HUSBAND_LEVEL_REQUEST);
    }

    @Override
    protected void response(IWomen women) {
        System.out.println("------------妻子向丈夫请示------------");
        System.out.println("妻子的请示是:" + women.getRequest());
        System.out.println("丈夫的答复是:同意");
    }
}
public class Son extends IHandler {

    public Son(){
        super(IHandler.SON_LEVEL_REQUEST);
    }
    @Override
    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 random = new Random();
        ArrayList arrayList = new ArrayList<>();
        for(int i = 0; i < 5; ++i){
            arrayList.add(new Women(random.nextInt(4), "宝宝中秋要去逛街"));
        }
        IHandler father = new Father();
        IHandler husband = new Husband();
        IHandler son = new Son();
        father.setNext(husband);
        husband.setNext(son);
        for(IWomen women:arrayList){
            father.HandlerMessage(women);
        }
    }
}

可能例子不是很好,但是”链“还是体现的很明显。责任链的缺点是当链很长的时候不好调试,并且影响了它的执行效率,所以我们要避免超长链的存在。

中秋节快乐~

你可能感兴趣的:(设计模式,设计模式之禅)