职责链模式

需求

  • 费用报销审批
  • 请求审批

代码实现

员工

image-20210926192031102

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 9:58
 * @description
 **/
@Data
public class Employee {
    private int money;
    public void getApply() {
        System.out.println("需要出差的费用是:" + getMoney());
    }
}

组长

image-20210927104036668

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:03
 * @description
 **/
public class GroupLeader {
    public void handler(Employee employee) {
        employee.getApply();
        System.out.println("我是组长:你需要申请的" + employee.getMoney() + "批准了");
    }
}

经理

image-20210927104148153

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:05
 * @description
 **/
public class Manager {
    public void handler(Employee employee) {
        employee.getApply();
        System.out.println("我是经理:你需要申请的" + employee.getMoney() + "批准了");
    }
}

总经理

image-20210927104341712

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:06
 * @description
 **/
public class GeneralManager {
    public void handler(Employee employee) {
        employee.getApply();
        System.out.println("我是总经理:你需要申请的" + employee.getMoney() + "批准了");
    }
}

客户端使用

image-20211012100921004

/**
 * 客户端
 *
 * @author BNTang
 */
public class Client {
    public static void main(String[] args) {
        GroupLeader groupLeader = new GroupLeader();
        Manager manager = new Manager();
        GeneralManager generalManager = new GeneralManager();

        Employee employee = new Employee();
        employee.setMoney(1000);

        if (employee.getMoney() <= 500) {
            groupLeader.handler(employee);
        } else if (employee.getMoney() <= 1000) {
            manager.handler(employee);
        } else if (employee.getMoney() <= 1500) {
            generalManager.handler(employee);
        }

        // 1.具体是谁申请出差费用我们不管,我们只管申请出差需要做那些事!
        // 2.具体是谁审批我们不需要纠结,我们只管审批需要做哪些事
    }
}

存在问题

  1. 具体是谁申请出差费用我们不管,我们只管申请出差需要做哪些事
  2. 具体是谁审批我们不需要纠结,我们只管审批需要做哪些事

责任链模式定义

可以在系统中建立一个链,这样消息可以在首先接收到它的级别处被处理,或者可以定位到可以处理它的对象。为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止

主要角色

抽象处理者(Handler)角色

定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

具体处理者(Concrete Handler)角色

实现抽象处理者的处理方法,判断能否处理本次请求,继者,如果可以处理请求则处理,否则将该请求转给它的后。

客户类(Client)角色

创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

责任链模式代码实现

将申请人操作抽象化

image-20210927133845751

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:22
 * @description 将申请人的操作抽象化,不需要关心是谁来申请出差费用,只关心出差申请要做的事
 **/
public abstract class ApplyPersonInfo {
    int money;

    /**
     * 设置钱
     *
     * @param money 钱
     */
    public abstract void setMoney(int money);

    /**
     * 得到钱
     *
     * @return int
     */
    public abstract int getMoney();

    public void getApply() {
        System.out.println("需要出差的费用是:" + getMoney());
    }
}

抽象处理类

image-20210927135511798

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:32
 * @description
 **/
public abstract class LeaderHandler {

    /**
     * 当前领导审核的金额
     */
    int auditMoney;

    /**
     * 上级领导
     */
    LeaderHandler superiorLeader;

    /**
     * 当前领导收到申请后处理的事情
     *
     * @param applyPersonInfo 申请人信息
     */
    public abstract void handler(ApplyPersonInfo applyPersonInfo);

    /**
     * 设置当前领导的上级领导
     *
     * @param superiorLeader 上级领导
     */
    public abstract void setSuperiorLeader(LeaderHandler superiorLeader);

    public void dealInfo(ApplyPersonInfo applyPersonInfo) {
        if (applyPersonInfo.money <= auditMoney) {
            handler(applyPersonInfo);
        } else {
            superiorLeader.dealInfo(applyPersonInfo);
        }
    }
}

具体处理者

组长

image-20210927135603774

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:38
 * @description
 **/
public class GroupLeader extends LeaderHandler {

    GroupLeader() {
        super.auditMoney = 500;
    }

    @Override
    public void handler(ApplyPersonInfo applyPersonInfo) {
        applyPersonInfo.getApply();
        System.out.println("我是组长,你需要申请的:" + applyPersonInfo.getMoney() + "我批准了");
    }

    @Override
    public void setSuperiorLeader(LeaderHandler superiorLeader) {
        super.superiorLeader = superiorLeader;
    }
}

经理

image-20210927135643514

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:38
 * @description
 **/
public class Manager extends LeaderHandler {

    Manager() {
        super.auditMoney = 1000;
    }

    @Override
    public void handler(ApplyPersonInfo applyPersonInfo) {
        applyPersonInfo.getApply();
        System.out.println("我是经理,你需要申请的:" + applyPersonInfo.getMoney() + "我批准了");
    }

    @Override
    public void setSuperiorLeader(LeaderHandler superiorLeader) {
        super.superiorLeader = superiorLeader;
    }
}

总经理

image-20210927135709683

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:38
 * @description
 **/
public class GeneralManager extends LeaderHandler {

    GeneralManager() {
        super.auditMoney = 1500;
    }

    @Override
    public void handler(ApplyPersonInfo applyPersonInfo) {
        applyPersonInfo.getApply();
        System.out.println("我是总经理,你需要申请的:" + applyPersonInfo.getMoney() + "我批准了");
    }

    @Override
    public void setSuperiorLeader(LeaderHandler superiorLeader) {
        super.superiorLeader = superiorLeader;
    }
}

修改 Employee.java:

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 9:58
 * @description
 **/
public class Employee extends ApplyPersonInfo {
    @Override
    public void setMoney(int money) {
        super.money = money;
    }

    @Override
    public int getMoney() {
        return super.money;
    }
}

客户端调用

image-20210927135750723

/**
 * @author BNTang
 * @program design-pattern-pro
 * @date Created in 2021/10/12 012 10:48
 * @description
 **/
public class Client {
    public static void main(String[] args) {
        GroupLeader groupLeader = new GroupLeader();
        Manager manager = new Manager();
        GeneralManager generalManager = new GeneralManager();

        groupLeader.setSuperiorLeader(manager);
        manager.setSuperiorLeader(generalManager);

        Employee employee = new Employee();
        employee.setMoney(1500);

        groupLeader.dealInfo(employee);
    }
}

UML 图

image-20210927135923557

优点

🐱‍🏍降低了耦合度

该模式降低了请求发送者和接收者的耦合度

🌵增强了系统的可扩展性

可以根据需要增加新的请求处理类,满足开闭原则

🐂增加新对象指定责任的灵活性

当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除责任

由于在一个类中产生的事件可以被发送到组成中的其他类处理器上,类的集合可以作为一个整体

🐤责任分担

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

缺点

不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理,对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

使用场景

多个对象可以处理一个请求,而其处理器却是未知的,想要在不指定确切的请求接收对象的情况下,向几个对象中的一个发送请求。可以动态地指定能够处理请求的对象集。

源码

  • JavaWeb Filter
posted @   BNTang  阅读(43)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示