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

来源:互联网 发布:keep软件下载 编辑:程序博客网 时间:2024/05/16 09:19

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

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

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

这里写图片描述

见代码:

/***女性接口仅两个方法,一个是获得当前的个人状况,通过返回值决定是结婚了还*是没结婚、丈夫是否在世等,另一个方法是要请示的内容,要出去逛街还是吃饭*/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<IWomen> 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,带着这些问题,我们重新设计类图

这里写图片描述
见代码:

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<IWomen> 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);        }    }}

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

中秋节快乐~

10 1
原创粉丝点击