java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java 职责链模式

详解Java设计模式之职责链模式

作者:十二Y

责任链模式是一种行为设计模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下

职责链模式

1、职责链模式介绍

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

在责任链模式中,请求通过一条链传递,每个对象都有机会处理请求。当一个对象无法处理请求时,它会将请求传递给链中的下一个对象,直到找到能够处理请求的对象为止。这种方式可以动态地组织和管理对象,使得请求发送者和接收者之间解耦,提高系统的灵活性和可扩展性。

1.1 职责链模式基本实现

职责链模式结构图:

责任链模式包含以下几个角色:

Handler类,定义一个处理请示的接口:

/**
 * @author Shier
 * CreateTime 2023/5/20 16:04
 * 处理请求的接口
 */
public abstract class Handler {
    protected Handler successor;
    /**
     * 设置继承者
     * @param successor
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    public abstract void handleRequest(int request);
}

ConcreteHandler类,具体处理者类,处理它所负责的请求,可访问它的 后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继 者。

ConcreteHandler1,当请求数为0~10则有权处理,否则转到下一位:

/**
 * @author Shier
 * CreateTime 2023/5/20 16:06
 */
public class ConcreteHandler1 extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 0 && request < 10) {
            // 当前处理者权限 0 ~ 9
            System.out.println(this.getClass().getSimpleName() + "处理了请求" + request);
        } else if (successor != null) {
            // 转移给下一个处理者
            successor.handleRequest(request);
        }
    }
}

ConcreteHandler2,当请求数为10~20则有权处理,否则转到下一位。

/**
 * @author Shier
 * CreateTime 2023/5/20 16:06
 */
public class ConcreteHandler2 extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 10 && request < 20) {
            // 当前处理者权限 10 ~ 19
            System.out.println(this.getClass().getSimpleName() + "处理了请求" + request);
        } else if (successor != null) {
            // 转移给下一个处理者
            successor.handleRequest(request);
        }
    }
}

ConcreteHandler3,当请求数为20~99则有权处理,否则转到下一位

/**
 * @author Shier
 * CreateTime 2023/5/20 16:06
 */
public class ConcreteHandler3 extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 20 && request < 100) {
            // 当前处理者权限 20 ~ 99
            System.out.println(this.getClass().getSimpleName() + "处理了请求" + request);
        } else if (successor != null) {
            // 转移给下一个处理者
            successor.handleRequest(request);
        }
    }
}

客户端代码,向链上的具体处理者对象提交请求。

/**
 * @author Shier
 * CreateTime 2023/5/20 16:09
 */
public class ChainClient {
    public static void main(String[] args) {
        ConcreteHandler1 handler1 = new ConcreteHandler1();
        ConcreteHandler2 handler2 = new ConcreteHandler2();
        ConcreteHandler3 handler3 = new ConcreteHandler3();
        // 设置职责链上下关系
        handler1.setSuccessor(handler2);
        handler2.setSuccessor(handler3);
        // 请求
        int[] request = {15, 67, 8, 9, 46, 1, 5, 23, 41};
        // 循环给最小矗立着提交请求,不同的数额,得不同的权限处理者处理
        for (int i : request) {
            handler1.handleRequest(i);
        }
    }
}

2、具体例子说明

在公司请假或者升职加薪,需要通过经理、总监、总经理的批准,不同身份有不同的权限。当然可以直接直接找总经理给你升职加薪😎

2.1 不使用职责链模式 - 加薪 / 请假

升值加薪:经理是没有权限的,要上报给总监,总监的回复也是没有权限管,只能再上报到总经理才有处理的权限

请假:经理只能处理请假两天的申请,再多就不可以。必须要上报给上司才有权限去处理这个请求。

// 申请类
public class Request {
    // 申请类别
    private String requestType;
    public String getRequestType(){
        return this.requestType;
    }
    public void setRequestType(String value){
        this.requestType = value;
    }
    //申请内容
    private String requestContent;
    public String getRequestContent(){
        return this.requestContent;
    }
    public void setRequestContent(String value){
        this.requestContent = value;
    }
    // 数量
    private int number;
    public int getNumber(){
        return this.number;
    }
    public void setNumber(int value){
        this.number = value;
    }
}
//管理者
public class Manager{
    protected String name;
    public Manager(String name){
        this.name = name;
    }
    public void getResult(String managerLevel,Request request){
        if (managerLevel == "经理"){
          if (request.getRequestType()=="请假" && request.getNumber()<=2)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
          else 
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,我无权处理");
        }
        else if (managerLevel == "总监"){
          if (request.getRequestType()=="请假" && request.getNumber()<=5)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
          else 
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,我无权处理");
        }
        else if (managerLevel == "总经理"){
          if (request.getRequestType()=="请假")
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");
          else if (request.getRequestType()=="加薪" && request.getNumber()<=5000)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,被批准");
          else if (request.getRequestType()=="加薪" && request.getNumber()>5000)
            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,再说吧");
        }
    }
}

客户端:

public class Test {
    public static void main(String[] args) {
        Manager manager = new Manager("金利");
        Manager director = new Manager("宗剑");
        Manager generalManager = new Manager("钟精励");
        Request request = new Request();
        request.setRequestType("加薪");
        request.setRequestContent("Shier请求加薪");
        request.setNumber(10000); 
        // 不同身份的人有不同的权限,进行处理结果
        manager.getResult("经理", request);
        director.getResult("总监", request);
        generalManager.getResult("总经理", request);
        Request request2 = new Request();
        request2.setRequestType("请假");
        request2.setRequestContent("Shier请假");
        request2.setNumber(3); // 权限级别
        manager.getResult("经理", request2);
        director.getResult("总监", request2);
        generalManager.getResult("总经理", request2);
    }
}

通过上面的程序,会发现一个问题管理者类,里面的方法比较长,太多的分支判断。类的责任太多,就违背了单一职责原则,同时增加新的项目时,要去修改这个方法,就违背了开发 - 封闭原则。下面就要用到职责链模式要简化这样开发业务场景 。

2.2 职责链模式 - 加薪 / 请假

将上面的程序进行重构,得到的代码结构图如下:

Request请求类:

/**
 * @author Shier
 * 申请类
 */
public class Request {
    // 申请类别
    private String requestType;
    public String getRequestType() {
        return this.requestType;
    }
    public void setRequestType(String value) {
        this.requestType = value;
    }
    //申请内容
    private String requestContent;
    public String getRequestContent() {
        return this.requestContent;
    }
    public void setRequestContent(String value) {
        this.requestContent = value;
    }
    // 数量
    private int number;
    public int getNumber() {
        return this.number;
    }
    public void setNumber(int value) {
        this.number = value;
    }
}

抽象管理者:

/**
 * @author Shier
 * CreateTime 2023/5/20 16:33
 * 抽象管理这类
 */
public abstract class Manager {
    protected String name;
    public Manager(String name) {
        this.name = name;
    }
    /**
     * 设置管理者上级
     */
    protected Manager superior;
    public void setSuperior(Manager superior) {
        this.superior = superior;
    }
    /**
     * 请求申请
     *
     * @param request
     */
    public abstract void requestApplications(Request request);
}

经理类就可以去继承这个'管理者'类,只需重写 '申请请求' 的方法

/**
 * @author Shier
 * CreateTime 2023/5/20 16:34
 * 普通经理类
 */
public class CommonManager extends Manager {
    public CommonManager(String name) {
        super(name);
    }
    @Override
    public void requestApplications(Request request) {
        if (request.getRequestType() == "请假" && request.getNumber() <= 2) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "天,被批准");
        } else if (this.superior != null) {
            this.superior.requestApplications(request);
        }
    }
}

总监同样继承抽象管理类

/**
 * @author Shier
 * CreateTime 2023/5/20 16:36
 * 总监
 */
public class Director extends Manager {
    public Director(String name) {
        super(name);
    }
    @Override
    public void requestApplications(Request request) {
        if (request.getRequestType() == "请假" && request.getNumber() <= 5) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "天,被批准");
        } else if (this.superior != null) {
            this.superior.requestApplications(request);
        }
    }
}

总经理同样继承管理者类,总经理的权限就是全部都需要处理。

/**
 * @author Shier
 * CreateTime 2023/5/20 16:36
 * 总经理
 */
public class GeneralManager extends Manager {
    public GeneralManager(String name) {
        super(name);
    }
    @Override
    public void requestApplications(Request request) {
        if (request.getRequestType() == "请假") {
            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "天,被批准");
        } else if (request.getRequestType() == "加薪" && request.getNumber() <= 5000) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "元,被批准");
        } else if (request.getRequestType() == "加薪" && request.getNumber() > 5000) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "元,再说吧");
        }
    }
}

测试类:

/**
 * @author Shier
 */
public class ChainClient {
    public static void main(String[] args) {
        CommonManager manager = new CommonManager("大明经理");
        Director director = new Director("大大明总监");
        GeneralManager generalManager = new GeneralManager("大大大明总经理");
        // 设置管理者之间上下级关系 经理 => 总监 => 总经理
        manager.setSuperior(director);
        director.setSuperior(generalManager);
        // 加薪 5000
        Request request = new Request();
        request.setRequestType("加薪");
        request.setRequestContent("Shier请求加薪");
        request.setNumber(5000);
        // 从自己最近的上司开始请求也就是经理
        manager.requestApplications(request);
        // 加薪10000
        Request request1 = new Request();
        request1.setRequestType("加薪");
        request1.setRequestContent("Shier请求加薪");
        request1.setNumber(10000);
        manager.requestApplications(request1);
        // 请假一天
        Request request2 = new Request();
        request2.setRequestType("请假");
        request2.setRequestContent("Shier请假");
        request2.setNumber(1);
        manager.requestApplications(request2);
        // 请假四天
        Request request3 = new Request();
        request3.setRequestType("请假");
        request3.setRequestContent("Shier请假");
        request3.setNumber(4);
        manager.requestApplications(request3);
    }
}

最后得到的结果:

由于我们把原来的一个 '管理者' 类改成了一个抽象类和三个具体类, 此时类之间的灵活性就大大增加了,如果我们需要扩展新的管理者类别,只需要增加子类就可以。比如这个例子增加一个 '集团总裁' 类,完全是没有问题的,只需要修改 '总经理类' 即可,并不影响其他类代码。

这样使用职责链模式可以更加清晰这些代码之间的关系,不像最上面的一个类里面多个判断语句,看起来都很难维护。好了,再总结一下职责链模式

3、职责链模式总结

职责链模式的好处

优点:

缺点:

使用场景:

以上就是详解Java设计模式之职责链模式的详细内容,更多关于Java 职责链模式的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文