Chain of Responsibility 责任链模式

时间:2023-03-08 20:27:29

简介
责任链模式是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其【下家】的引用而连接起来形成一条链,请求在这个链上【传递】,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心。

责任链有一个缺点是,大家在开发的时候要注意,调试不是很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。

适用性
1.有多个的对象可以处理一个请求,具体哪个对象处理该请求在运行时刻自动确定。
2.你在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3.可处理一个请求的对象集合应被动态指定。

作用:请求会被链上的对象处理,但是客户端不知道请求会被哪些对象处理
通过把请求从一个对象传递到链条中下一个对象的方式,直到请求被处理完毕,以实现对象间的解耦。
JDK中体现:
(1)java.util.logging.Logger会将log委托给parent logger
(2)ClassLoader的委托模型

简易演示-1
中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父、既嫁从夫、夫死从子”,也就是说一个女性,在没有结婚的时候要听从于父亲,结了婚后听从于丈夫,丈夫死了还要听儿子的。举个例子来说,一个女的要出去逛街,同样这样的一个请求,在她没有出嫁前她必须征得父亲的同意,出嫁之后必须获得丈夫的许可,那丈夫死了怎么办?一般都是男的比女的死的早,还要问问儿子是否允许自己出去逛街。父亲、丈夫、儿子只有两种选择:要不承担起责任来告诉她允许或不允许逛街,要不就让她请示下一个人,这是整个社会体系的约束,应用到我们项目中就是业务规则,那我们来看怎么把“三从”通过我们的程序来实现。
public class Test2 {
    public static void main(String[] args) {
        //定义三个请示对象
        Handler father = new Father();
        Handler husband = new Husband();
        Handler son = new Son();
        //设置请示顺序
        father.setNext(husband);
        husband.setNext(son);

        //随机挑选几个女性
        ArrayList<IWomen> arrayList = new ArrayList<IWomen>();
        for (int i = 0; i < 5; i++) {
            arrayList.add(new Women(new Random().nextInt(4), "我要出去逛街"));
        }

        //处理请示
        for (IWomen women : arrayList) {
            father.HandleMessage(women);
        }
    }
}

interface IWomen {
    /**获得个人状况*/
    public int getType();
    /**获得个人请示,你要干什么?出去逛街?约会?还是看电影*/
    public String getRequest();
}
class Women implements IWomen {
    /** 描述妇女的个人状况 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;
            break;
        }
    }
    @Override
    public int getType() {
        return this.type;
    }
    @Override
    public String getRequest() {
        return this.request;
    }
}

abstract class Handler {
    /**能处理的状况*/
    private int type = 0;
    /**责任传递,下一个人责任人是谁*/
    private Handler nextHanlder;
    public Handler(int type) {
        this.type = type;
    }
    //一个女性(女儿,妻子或者是母亲)要求逛街,你要处理这个请求
    public final void HandleMessage(IWomen women) {
        if (women.getType() == this.type) response(women);//自己处理
        else if (nextHanlder != null) nextHanlder.HandleMessage(women); //有后续环节,才把请求往后递送
        else System.out.println("-----------没有人可以请示了,不做处理!---------\n");//已经没有后续处理人了,不用处理了
    }
    public void setNext(Handler _handler) {
        this.nextHanlder = _handler;
    }
    /**回应*/
    public abstract void response(IWomen women);
}
/**父亲类,父亲只处理女儿的请求*/
class Father extends Handler {
    public Father() {
        super(1);
    }
    @Override
    public void response(IWomen women) {
        System.out.println("--------女儿向父亲请示-------");
        System.out.println(women.getRequest());
        System.out.println("父亲的答复是:同意\n");
    }
}
/**丈夫类,丈夫只处理妻子的请求*/
class Husband extends Handler {
    public Husband() {
        super(2);
    }
    //丈夫请示的答复
    @Override
    public void response(IWomen women) {
        System.out.println("--------妻子向丈夫请示-------");
        System.out.println(women.getRequest());
        System.out.println("丈夫的答复是:同意\n");
    }
}
/**儿子类*/
class Son extends Handler {
    public Son() {
        super(3);
    }
    @Override
    public void response(IWomen women) {
        System.out.println("--------母亲向儿子请示-------");
        System.out.println(women.getRequest());
        System.out.println("儿子的答复是:同意\n");
    }
}

简易演示-2
/**请求 */
public interface IRequest {
    public void request();
}
/**加薪请求 */
class AddMoneyRequest implements IRequest {
    @Override
    public void request() {
        System.out.print("加薪请求-->");
    }
}
/**离职请求 */
class DimissionRequest implements IRequest {
    @Override
    public void request() {
        System.out.print("离职请求-->");
    }
}
/**请假请求 */
class LeaveRequest implements IRequest {
    @Override
    public void request() {
        System.out.print("请假请求-->");
    }
}

/**请求处理接口 */
public interface IRequestHandle {
    void handleRequest(IRequest request);
}
/**项目经理处理,审批AddMoneyRequest的请求 */
class PMRequestHandle implements IRequestHandle {
    private IRequestHandle nextHandle;
    public PMRequestHandle(IRequestHandle rh) {
        this.nextHandle = rh;
    }
    @Override
    public void handleRequest(IRequest request) {
        if (request instanceof AddMoneyRequest) System.out.println("项目经理审批完毕");
        else nextHandle.handleRequest(request);
    }
}
/**项目组长处理,审批LeaveRequest的请求*/
class TLRequestHandle implements IRequestHandle {
    private IRequestHandle nextHandle;
    public TLRequestHandle(IRequestHandle rh) {
        this.nextHandle = rh;
    }
    @Override
    public void handleRequest(IRequest request) {
        if (request instanceof LeaveRequest) System.out.println("项目组长审批完毕");
        else nextHandle.handleRequest(request);
    }
}
/**最后的审批者,人事处理,审批其他请求 */
class LastRequestHandle implements IRequestHandle {
    @Override
    public void handleRequest(IRequest request) {
        System.out.println("人事审批完毕");
    }
}

/**
 * 责任链模式。使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
 * 将这些对象连成一条链,并沿着这条链【传递】该请求,直到有一个对象处理它为止。
 */
public class Test {
    public static void main(String[] args) {
        IRequest request1 = new DimissionRequest();
        IRequest request2 = new AddMoneyRequest();
        IRequest request3 = new LeaveRequest();

        IRequestHandle handle = new TLRequestHandle(new PMRequestHandle(new LastRequestHandle()));
        request1.request();
        handle.handleRequest(request1);
        request2.request();
        handle.handleRequest(request2);
        request3.request();
        handle.handleRequest(request3);
        System.out.println("\n");
        IRequestHandle handle2 = new PMRequestHandle(new TLRequestHandle(new LastRequestHandle()));//顺序无影响
        handle2.handleRequest(request1);
        handle2.handleRequest(request2);
        handle2.handleRequest(request3);
    }
}

附件列表