设计模式之责任链模式

595 阅读4分钟

       作为一个程序员,我们的代码都是进行统一的管理的,同样会进行一些权限的控制。比如我们想申请一些非核心代码,向权限管理员申请下即可。想申请核心代码的权限,可能权限管理员都没权利开放,需要项目经理处理。申请支付等关键代码,可能需要技术总监来处理。这样一个场景使用责任链模式来进行处理就能很好地进行。

一、定义

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

重点:

1、对请求进行处理的对象链成一条处理链,如:A持有B引用、B持有C的引用、C持有D的引用,形成一条处理链。

2、请求在链上传递,直到某个对象处理请求。如:A处理不了则让B处理、B处理不了让C处理、C处理不了让D处理

二、UML图

下图中,我们定义了抽象类Handler表示处理请求的角色。具体实现有CommonManage 普通管理员,只能处理非核心代码权限开发。ProjectManage 项目经理,能开放核心代码权限。ChiefTechnologyOfficer、能开发所有代码权限,包括支付等核心中的核心。


三、实例

代码实现,为更好抽象,请求封装成一个Request对象

package com.design.responsibility;

public class Request {

    /**
     *请求code
     * 1表示普通代码
     * 2表示核心代码
     * 3表示支付等核心中核心代码
     */
    public int code;

    public String message;

    public Request(int code, String message){
        this.code = code;
        this.message = message;
    }


    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

抽象处理类

package com.design.responsibility;

public abstract  class Handler {
    //责任链下一节点对象
    Handler nextHandleObj;

    public Handler getNextHandleObj() {
        return nextHandleObj;
    }

    public void setNextHandleObj(Handler nextHandleObj) {
        this.nextHandleObj = nextHandleObj;
    }
    //处理请求的方法
    public abstract void handleRequest(Request request);
}

具体的处理类

普通管理员,只能开发非核心代码权限

package com.design.responsibility;
//普通管理员,只能开发非核心代码权限
public class CommonManage extends Handler {

    @Override
    public void handleRequest(Request request) {
        if(request.getCode() == 1){
            System.out.println("请求:"+request.getMessage()+",普通管理员:已经为您开放非核心代码权限!!");
        }else{
            //没有处理权限,让责任链下一个节点去处理
            super.nextHandleObj.handleRequest(request);
        }
    }

}

项目经理,能开放非核心代码、核心代码权限

package com.design.responsibility;

public class ProjectManage extends Handler {

    @Override
    public void handleRequest(Request request) {
        if (request.getCode() < 3){
            System.out.println("请求:"+request.getMessage()+",项目经理:已经为您开放非支付核心代码权限!!");
        }else {
            //没有开发支付核心代码权限,让责任链下一节点去处理
            super.nextHandleObj.handleRequest(request);
        }
    }
}

技术总监、能开放所有代码权限

package com.design.responsibility;

public class ChiefTechnologyOfficer extends Handler {

    @Override
    public void handleRequest(Request request) {
        System.out.println("请求:"+request.getMessage()+",技术总监:已经为您开放代码权限!!");
    }

}

测试代码如下

package com.design.responsibility;

public class TestMain {

    public static void main(String[] args) {
        //构建责任链  commonManage  -》 projectManage  -》 chiefTechnologyOfficer
        CommonManage commonManage = new CommonManage();
        ProjectManage projectManage = new ProjectManage();
        ChiefTechnologyOfficer chiefTechnologyOfficer = new ChiefTechnologyOfficer();
        commonManage.setNextHandleObj(projectManage);
        projectManage.setNextHandleObj(chiefTechnologyOfficer);
        //申请非核心代码权限
        Request comCode =new Request(1,"非核心代码");
        commonManage.handleRequest(comCode);
        //申请核心代码权限
        Request coreCode =new Request(2,"核心代码");
        commonManage.handleRequest(coreCode);
        //申请支付代码权限
        Request payCode =new Request(3,"支付核心代码");
        commonManage.handleRequest(payCode);

    }
}

执行结果


从结果可以看到,申请不同的代码权限,处理的类是不同的,申请非核心代码,处理类是普通管理员,申请核心代码,处理类是项目经理,申请支付核心代码,处理类是技术总监。处理不了的请求就沿着处理链往下传递请求。

四、总结

从定义中,我们可以知道责任链模式主要应用在处理请求上。一个请求交予一条责任链去处理,责任链上能进行处理的类就进行处理,否则继续沿着责任链传递请求。

优点:

1、定义处理类非常灵活,新增处理类,只需新增类并继承自抽象处理类,增加到处理链上即可。

2、责任链上处理类处理顺序调整灵活。

3、请求发送者跟处理者解耦,发送者只需发送一个请求,并不需要知道责任链上哪个节点处理了请求。

缺点:

1、不能保证责任链一定对请求进行了处理。

2、测试相对麻烦,如果编写错误,还可能组成环状责任链,造成代码死循环。

参考:

《大话设计模式》