设计模式-------责任链模式

一,简介

        责任链模式是行为型模式的一种,它的原始定义是:避免将一个请求发送者与接收者耦合在一起,让多个对象都有机会处理请求,将接收请求的对象连城一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止。

        在责任链模式中,多个处理器(也就是定义中说的接收对象)依次处理同一个请求, 一个请求先经过A处理器处理,然后交由B处理器处理,B处理器处理完在交给C处理器,依此类推,链条上的每个处理器各自承担各自的处理职责,所以叫做职责链模式。

二、原理

职责链模式由以下几种角色组成

①抽象处理者:包含一个抽象处理方法,保存一个next的抽象处理者成员变量

②具体实现:实现抽象处理者。

③客户端:创建处理链

三、实现

结构实现

1)请求数据封装类

/**
 * 请求数据类
 */
public class RequestData {
    private String data;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

2)抽象处理者类

/**
 * 抽象处理类
 */
public abstract class Handler {
    
    //后继处理者
   protected  Handler next;
    
    //处理方法
    public abstract void process(RequestData requestData);
}

3)具体处理者

/**
 * 具体处理者
 */
class HandlerA extends Handler{

    @Override
    public void process(RequestData requestData) {
        System.out.println("HandlerA 处理数据:"+requestData);
        requestData.setData(requestData.getData().replace("A",""));
        //判断是否有后继处理者
        if (next!=null){
            next.process(requestData);
        }else {
            System.out.println("处理结束");
        }
        
    }
}

class HandlerB extends Handler{

    @Override
    public void process(RequestData requestData) {
        System.out.println("HandlerB 处理数据:"+requestData);
        requestData.setData(requestData.getData().replace("B",""));
        //判断是否有后继处理者
        if (next!=null){
            next.process(requestData);
        }else {
            System.out.println("处理结束");
        }

    }
}

4)客户端类

class Client{
    public static void main(String[] args) {
        //创建请求数据
        RequestData data = new RequestData();
        data.setData("ABC");
        //创建处理器
        Handler a = new HandlerA();
        Handler b = new HandlerB();
        Handler c = new HandlerC();
       //设置链条
        a.setNext(b);
        b.setNext(c);
        //执行方法
        a.process(data);
        /**
         * HandlerA 处理数据:RequestData{data='ABC'}
         * HandlerB 处理数据:RequestData{data='BC'}
         * HandlerC 处理数据:RequestData{data='C'}
         * 处理结束
         */
    }
}

 场景实现

        接下来我们模拟一个有双11期间业务系统审批的流程,临近双十一公司会有陆续有一些新的需求上线,为了保证线上系统的稳定,我们对上线的审批流畅做了严格的控制,审批的过程会有不同级别的负责人加入进行审批(平常系统上线只需三级负责人审批即可,双十一前后需要二级或一级审核人参与审批),接下来我们就使用职责链模式来设计一下此功能。

1)不使用设计模式

/**
 * 审核信息
 */
public class AuthInfo {
    //审核编码
    private String code;
    //审核信息
    private String info="";

    public AuthInfo(String code, String info) {
        this.code = code;
        this.info = info;
    }

}


/**
 * 处理信息抽象接口
 */
public interface Approval {
    void processAuthInfo(AuthInfo authInfo);
}

class  ThreeApproval implements Approval{

    @Override
    public void processAuthInfo(AuthInfo authInfo) {
        System.out.println("三级审批处理信息");
    }
}

class TwoApproval implements Approval{

    @Override
    public void processAuthInfo(AuthInfo authInfo) {
        System.out.println("二级审批处理信息");
    }
}
class OneApproval implements  Approval{

    @Override
    public void processAuthInfo(AuthInfo authInfo) {
        System.out.println("一级审批处理信息");
    }
}


public class Client1 {
    public static void main(String[] args) {
        AuthInfo authInfo = new AuthInfo("110", "123");
        System.out.println("双十一之前");
        ThreeApproval threeApproval = new ThreeApproval();
        threeApproval.processAuthInfo(authInfo);

        System.out.println("双十一时");
        TwoApproval twoApproval = new TwoApproval();
        threeApproval.processAuthInfo(authInfo);
        OneApproval oneApproval = new OneApproval();
        oneApproval.processAuthInfo(authInfo);

        /**
         * 双十一之前
         * 三级审批处理信息
         * 双十一时
         * 三级审批处理信息
         * 一级审批处理信息
         */
    }
}

        通过以上实例我们可以看出,我们要完成整个流程,每一个节点都需要我们手动的调用算法,具体的调用由客户端直接去操作,而有时候调用者不需要关注其他节点的信息,只需要将任务交由一个节点去处理,具体后续节点的处理我并不关心 ,那么我们该如何改造呢?

2)使用设计模式



/**
 * 审批处理器抽象类
 */
public abstract class Approve {
    //后继处理者
    protected Approve next;

    public void setNext(Approve next) {
        this.next = next;
    }

    //后继处理方法
    abstract  void processApprove(AuthInfo authInfo);

}

/**
 * 三级审批
 */
 class  ThreeApprove extends  Approve{

    @Override
    void processApprove(AuthInfo authInfo) {
        authInfo.setInfo("三级审批完成");
        if (next!=null){
            System.out.println("三级审批完成,开始处理二级");
           next.processApprove(authInfo);
        }else {
            System.out.println("处理结束");
        }

    }
}

/**
 * 二级审批
 */
class  TwoApprove extends  Approve{

    @Override
    void processApprove(AuthInfo authInfo) {
        authInfo.setInfo("二级审批完成");
        if (next!=null){
            System.out.println("二级审批完成,开始处理一级");
            next.processApprove(authInfo);
        }else {
            System.out.println("处理结束");
        }
    }
}

/**
 * 一级审批
 */
class  OneApprove extends  Approve{

    @Override
    void processApprove(AuthInfo authInfo) {
        authInfo.setInfo("一级审批完成");
        if (next!=null){
            next.processApprove(authInfo);
        }else {
            System.out.println("处理结束");
        }
    }
}

class  Client2{
    public static void main(String[] args) {
        AuthInfo authInfo = new AuthInfo("1", "");
        //模拟双十一:假设双十一需要三级审批

        //创建处理器
        ThreeApprove three = new ThreeApprove();
        TwoApprove two = new TwoApprove();
        OneApprove one = new OneApprove();

        //设置链路
        three.setNext(two);
        two.setNext(one);

        //开始调用
        three.processApprove(authInfo);

        /**
         * 三级审批完成,开始处理二级
         * 二级审批完成,开始处理一级
         * 处理结束
         */
    }
}

            通过上述实例我们很容易发现,处理方式较不使用设计模式更加容易维护,调用者只需要关注第一层处理器即可,其余层次不需要调用,如果后续增加了新的链路我们只需要挪动next就可以,无需改动代码,符合开闭原则,使代码可读性加强,更容易维护。

四、总结

优点 

①降低了对象之间的耦合度:该模式降低了请求者和发送者的耦合度

②增强了系统的可扩展性:可以根据需要增加新的请求处理类,满足开闭原则

③增强了对象指派职责的灵活性:当工作流程发生变化,可以动态的改变链内的成员或者修改它们的次序,也可动态的新增或者删除责任

④责任链简化了对象之间的链接:一个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的应用,这避免了众多的if-else语句。

⑤责任分担 :每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

缺点

①不能保证每个请求一定被处理,由于一个请求没有明确的接收者,所以不能保证它有一定会被处理,该请求可能一直传到末端都得不到处理。

②对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能受到一定的影响。

③职责链的合理性靠客户端来保证,增加了客户端的复杂性,可能会由于职责链错误而导致系统出错,如可能会造成循环调用。

使用场景

责任链模式场景的使用场景有以下几种情况

①在运行时需要使用多个关联对象来处理同一请求,比如:请假流程,员工入职流程等。

②不想让使用者知道具体的逻辑时,比如做权限校验或拦截器

③需要动态的更换处理对象时,比如:工单处理系统

④职责链模式常常被用在框架中,比如过滤器,拦截器等等

  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值