java使用责任链模式进行优化代码

1.什么是责任链

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。每个收到请求的对象要么处理该请求,要么将它传递给链中的下一个对象。

责任链模式的优点:

  1. 降低耦合度:

    • 发送者无需知道请求的接收者是谁,也不需要知道请求如何被处理。
    • 接收者也不需要知道其他接收者的存在。
  2. 增强给请求的处理灵活性:

    • 可以动态地增删处理者。
    • 处理者可以根据条件决定是否处理请求。
  3. 简化了对象:

    • 请求的发送者和接收者之间无需建立直接联系。

责任链模式的缺点:

  1. 可能导致难以调试:

    • 如果链很长,可能会导致难以追踪请求的处理过程。
  2. 可能不易于维护:

    • 当链的结构变得复杂时,维护起来可能比较困难。

2.使用场景

责任链的使用场景还是比较多的:

  • 多条件流程判断:权限控制

  • ERP 系统流程审批:总经理、人事经理、项目经理

  • Java 过滤器的底层实现 Filter

  • 多级审批:如报销审批、请假申请等。

  • 异常处理:不同类型的异常可以被不同的处理者捕获和处理。

  • 过滤器:在网络通信中,多个过滤器可以处理同一个请求或响应。

如果不使用该设计模式,那么当需求有所改变时,就会使得代码臃肿或者难以维护,例如下面的例子。

3.反例

假设现在又一个审批流程,进入下一个审批流程的条件是当前审批流程审批通过

组长审批通过-->主管审批通过-->项目经理审批通过

那么代码可以这样写

java 复制代码
//第一步
public class GroupLeaderHandler {
    public Boolean handler(){
        System.out.println("第一步-->GroupLeaderHandler");
        return true;
    }
}

//第二步
public class ManagerHandler {
    public Boolean handler(){
        System.out.println("第二步-->ManagerHandler");
        return true;
    }
}


//第三步
public class ProjectManagerHandler {
    public Boolean handler(){
        System.out.println("第三步-->ProjectManager,这是最后一步啦");
        return true;
    }
}


//客户端
publicclass HandlerClient {
    public static void main(String[] args) {

        GroupLeaderHandler groupLeaderHandler = new GroupLeaderHandler();
        ManagerHandler managerHandler = new ManagerHandler();
        ProjectManagerHandler projectManagerHandler = new ProjectManagerHandler();

        boolean groupLeaderFlag = groupLeaderHandler.handler();
        if(groupLeaderFlag){
            boolean managerFlag = managerHandler.handler();
            if(managerFlag){
                projectManagerHandler.handler();
            }
        }
    }
}

如果审批的人10个甚至更多,我们的代码可能就会写成这样

java 复制代码
if(第1步审核通过){
     // 第2步审核
    if(第2步审核通过){
        // 第3步审核
        if(第3步审核通过){
           // 第4步审核
            if(第4步审核通过){
                // 第5步审核
                if(第5步审核通过){
                    // 第6步审核
                    if(第6步审核通过){
                        //...
                    }
                }
            } 
        }
    }
}

这种代码不仅冗余,并且当我们要将某两关进行调整时对代码的改动非常大,这种操作的风险是很高的,因此,这是一种非常糟糕的写法。

4.使用责任链和工厂进行改造

java 复制代码
/**
 * 审核接口也可以使用抽象类
 */
public interface Approver {
    void handler();
    void setNextApprover(Approver nextApprover);
}

/**
 * 行政部
 */
public class AdministrationDepartment implements Approver{

    private Approver nextApprover;

    @Override
    public void handler() {
        System.out.println("行政部审批通过");
         if (nextApprover != null) {
             nextApprover.handler();
         }
    }

    @Override
    public void setNextApprover(Approver nextApprover) {
         this.nextApprover = nextApprover;
    }
}


/**
 * 财务部
 */
public class FinanceDepartment implements Approver{

    private Approver nextApprover;

    @Override
    public void handler() {
        System.out.println("财务部审批通过");
        if (nextApprover != null) {
            nextApprover.handler();
        }
    }

    @Override
    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }
}


/**
 * 总经理
 */
public class GeneralManager implements Approver{

    private Approver nextApprover;

    @Override
    public void handler() {
        System.out.println("总经理审批通过");
        if (nextApprover != null) {
            nextApprover.handler();
        }
    }

    @Override
    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }
}


/**
 * 工厂类:在工厂类中配置审批流程,形成责任链
 */
public class ApprovalProcessFactory {

    public static List<Approver> approvers;

    static {
        approvers = Arrays.asList(new AdministrationDepartment(),
                    new FinanceDepartment(), new GeneralManager(), new CEO());
    }

    public static Approver  createApprovalProcess() {
        // 将处理器按顺序链接成责任链
        for (int i = 0; i < approvers.size() - 1; i++) {
            approvers.get(i).setNextApprover(approvers.get(i + 1));
        }
        return approvers.get(0);
    }
}

//测试类
public class ApprovalProcessTest {

    public static void main(String[] args) {
        Approver approvalProcess = ApprovalProcessFactory.createApprovalProcess();
        approvalProcess.handler();
    }
}
相关推荐
fdc201711 天前
解耦的艺术:用责任链模式构建可插拔的文件处理流水线
c#·.net·责任链模式
YigAin21 天前
Unity23种设计模式之 责任链模式
设计模式·责任链模式
柏木乃一22 天前
进程间通信IPC(3)system V标准下基于责任链模式的消息队列,基于建造者模式的信号量
linux·c++·消息队列·建造者模式·责任链模式·信号量·进程间通信ipc
书院门前细致的苹果25 天前
设计模式大全:单例、工厂模式、策略模式、责任链模式
设计模式·责任链模式·策略模式
苏渡苇1 个月前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
短剑重铸之日1 个月前
《设计模式》第十篇:三大类型之行为型模式
java·后端·设计模式·责任链模式·访问者模式·行为型模式
刀法孜然1 个月前
Chain of Responsibility 职责链模式
责任链模式
小码过河.1 个月前
设计模式——责任链模式
设计模式·责任链模式
Engineer邓祥浩1 个月前
设计模式学习(25) 23-23 责任链模式
学习·设计模式·责任链模式
虫小宝2 个月前
基于责任链模式构建可扩展的微信群发消息风控过滤器(Java实现)
android·java·责任链模式