《设计模式之禅》学习之 “责任链模式”

BAT 批处理程序 2017-05-07

本章一开始举了中国古代对妇女制定的 “三从四德” 的道德规范,形象地将女性在 “未嫁-> 出嫁 -> 丧父” 三个不同的状态下请示出门逛街获得的处理,未嫁的时候,请示父亲;出嫁了,请示丈夫;丈夫去世了,请示儿子。责任链就是:父亲 -> 丈夫 -> 儿子。如果出嫁了,请示父亲,会得到什么结果?答案是:父亲告诉他,你该去请示你的丈夫。读完还是蛮形象的。 其实,作者给我们阐述了这么一个场景:一个请求到来的时候,请求方并不知道也不必知道谁去处理请求,责任链也不必关心谁发出的请求。请求来了,从第一个处理者开始,如果属于这一层,就处理。不属于?分发到下一个节点。下一个不能处理怎么办?再下一个。寻找处理者就是遍历链表节点的过程。 为什么这么做?这样做,就避免了请求和处理耦合在一起,代码也简洁了很多。 Talk is cheap, show me the code. 先创建一个女性接口:

public interface IWomen {

    // 获得个人状态.
    public int getType();

    // 获得个人请示
    public String getRequest();
}

创建一个古代妇女:

public class Women implements IWomen {

    /**
     * 通过 int 类型的参数来描述妇女的个人状况.
     * <p/>
     * 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;
        }
    }

    /**
     * 获取自己的状态.
     *
     * @return
     */
    public int getType() {
        return this.type;
    }

    /**
     * 获取妇女的请求.
     *
     * @return
     */
    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;
    }

    /**
     * 处理女性的请求.
     *
     * @param women
     */
    public final void HandleMessage(IWomen women) {
        if (women.getType() == this.level) {
            this.response(women);
        } else {
            if (null != this.nextHandler) {
                this.nextHandler.HandleMessage(women);
            } else {
                // 没有后续的处理人了.
                System.out.println("\n-------没有地方请示了,按不同意处理-------\n");
            }
        }
    }

    /**
     * 如果不属于该类处理的请求,应该将其设置到下一个需要请求的环节.
     *
     * @param handler
     */
    public void setNextHandler(Handler handler) {
        this.nextHandler = handler;
    }

    /**
     * 有请求肯定要有回应
     *
     * @param women
     */
    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("\n-------女儿向父亲请示-------");
        System.out.println(women.getRequest());
        System.out.println("父亲的回答是: 同意\n");
    }
}

丈夫类:

public class Husband extends Handler {

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

    @Override
    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);
    }

    @Override
    protected void response(IWomen women) {
        System.out.println("-------母亲向儿子请示-------");
        System.out.println(women.getRequest());
        System.out.println("儿子的答复是: 同意\n");
    }
}

场景类:

public class Client {
    public static void main(String[] args) {
        Random random = new Random();
        ArrayList<IWomen> arrayList = new ArrayList<IWomen>();

        for (int i = 0; i < 5; i++) {
            arrayList.add(new Women(random.nextInt(4), "我要去逛街"));
        }

        // 定义三个请求对象
        Father father = new Father();
        Husband husband = new Husband();
        Son son = new Son();

        father.setNextHandler(husband);
        husband.setNextHandler(son);

        for (IWomen women : arrayList) {
            father.HandleMessage(women);
        }
    }
}

运行结果:

-------母亲向儿子请示-------
母亲的请求是: 我要去逛街
儿子的答复是: 同意

-------妻子向丈夫请示-------
妻子的请求是: 我要去逛街
丈夫的答复是: 同意
-------母亲向儿子请示-------
母亲的请求是: 我要去逛街
儿子的答复是: 同意


-------没有地方请示了,按不同意处理-------

-------妻子向丈夫请示-------
妻子的请求是: 我要去逛街
丈夫的答复是: 同意

在抽象类 Handler 中,我们设置了级别 level 的参数用来标示子类的等级;定义了 nextHandler 来制定当前节点的下一个处理节点。这样,每个子类在生成实例对象的时候,通过指定下一个节点,就可以生成责任链了。 责任链模式的重点是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果。其优点就是将请求和处理分开来了。请求者不需要知道谁将处理这个请求,处理者也不要知道谁发起了这个请求。两者解耦,提高了系统的灵活性。

相关推荐