设计模式之责任链模式

责任链模式是一种设计模式,通过串联处理器形成处理链,请求从链头开始,由每个处理器依次处理,降低了客户端与处理器间的耦合。在请假系统中,通过创建不同权限的处理器(如组长、经理、总经理),模拟了该模式的应用,实现了请假审批流程。此外,还展示了过滤器模式,通过过滤器链进行请求的预处理和后处理。这种模式提高了系统的扩展性和可维护性,但也可能带来处理不确定性和性能影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式之责任链模式

概括

有时会遇到这样的情况,一个请求有多个请求处理者,每个请求处理者的权限不同,我们要用请求到每个处理者挨个请求,这样就造成的代码之间的巨大耦合度
可以把每个请求处理者,以链式的方式串接起来,我们只需要请求第一个处理者,第一个处理者处理不了,由当前处理者把请求转到下一个处理者,直到请求处理完成
这样我们不需要关注请求处理的具体过程,也大大减小了客户端与多个处理器之间的耦合度
这就是责任链模式,也叫职责链模式
在这里插入图片描述

结构

  • 客户:创建处理器链,并向链头发起请求
  • 抽象处理器:处理器的父接口或抽象类,声名链下一个处理器对象(类似链表的形式),并声明处理方法,
  • 具体处理器:重写处理器方法,如果当前处理器可以处理,则处理;否则调用下一个处理器的处理方法(可以抽取到抽象处理器中)

例子

请假:员工发出请假请求,每个领导的权限不同,允许批假的天数不同,组长可以批1天以内,经理可以批3天以内,总经理可以批7天以内,
如果请假天数超过7天,不批假

  • 请求对象:请假条
  • 用来在处理器链中传递请求
public class LeaveRequest {
	// 请假人
    private String name;
    // 请假天数
    private Integer day;
    // 请假理由
    private String content;
	// constructor
	// getter
	// setter
}
  • 抽象处理器
public abstract class Handler {

    public static final int NUM_ONE = 1;
    public static final int NUM_THERE = 3;
    public static final int NUM_SEVEN = 7;

    protected int numStart;
    protected int numEnd;

    /**
     * 处理链,下一个
     */
    protected Handler nextHandler;

    public Handler(int numStart, int numEnd) {
        this.numStart = numStart;
        this.numEnd = numEnd;
    }

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 每个子处理器的单独 逻辑
     */
    protected abstract void HandlerLeave(LeaveRequest leaveRequest);

    /**
     * 处理器的公共逻辑
     */
    public void submit(LeaveRequest leaveRequest) {
        // 如果请假的天数 小于 当前最大的处理天数, 处理
        // TODO 当前处理器可以处理
        if (leaveRequest.getDay() <= this.numEnd) {
            // 执行每个 子处理器 的 单独逻辑
            this.HandlerLeave(leaveRequest);
            System.out.println("处理完成");
        } else {
            // TODO 【核心】 当前处理器不能处理
            // 如果有下一个,执行链,让下一个处理
            if (this.nextHandler != null) {
                this.nextHandler.submit(leaveRequest);
            } else {
                // 走到 责任链 尽头
                System.out.println("不批假");
                System.out.println("处理失败");
            }
        }
    }

}
  • 具体处理器
public class GroupLeader extends Handler{
    public GroupLeader() {
        super(0, Handler.NUM_ONE);
    }
    @Override
    protected void HandlerLeave(LeaveRequest leaveRequest) {
        System.out.println("请假人:" + leaveRequest.getName());
        System.out.println("请假时间:" + leaveRequest.getDay());
        System.out.println("请假原因:" + leaveRequest.getContent());
        System.out.println(this.getClass().getSimpleName() + " 请假批准");
    }
}
public class GeneralMagager extends Handler{
    public GeneralMagager() {
        super(Handler.NUM_THERE, Handler.NUM_SEVEN);
    }
    @Override
    protected void HandlerLeave(LeaveRequest leaveRequest) {
        System.out.println("请假人:" + leaveRequest.getName());
        System.out.println("请假时间:" + leaveRequest.getDay());
        System.out.println("请假原因:" + leaveRequest.getContent());
        System.out.println(this.getClass().getSimpleName() + " 请假批准");
    }
}
public class Manager extends Handler{
    public Manager() {
        super(Handler.NUM_ONE, Handler.NUM_THERE);
    }
    @Override
    protected void HandlerLeave(LeaveRequest leaveRequest) {
        System.out.println("请假人:" + leaveRequest.getName());
        System.out.println("请假时间:" + leaveRequest.getDay());
        System.out.println("请假原因:" + leaveRequest.getContent());
        System.out.println(this.getClass().getSimpleName() + " 请假批准");
    }
}
  • 客户端
  • 创建处理器链
  • 向链头发出请求
public class Client {

    public static void main(String[] args) {
        // 创建请假条
        LeaveRequest leaveRequest = new LeaveRequest("张三", 1, "因病");

        // 创建责任链
        GroupLeader groupLeader = new GroupLeader();
        Manager manager = new Manager();
        GeneralMagager generalMagager = new GeneralMagager();
		// 设置链条
        groupLeader.setNextHandler(manager);
        manager.setNextHandler(generalMagager);

        // 请假提交,向链头发出请求
        groupLeader.submit(leaveRequest);
    }
}

模拟Filter过滤器

public interface Request {
}
public interface Response {
}
/**
 * 抽象处理器
 */
public interface Filter {
    void doFilter(Request req, Response resp, FilterChain chain);
}
  • 具体处理器
public class Filter01 implements Filter{
    @Override
    public void doFilter(Request req, Response resp, FilterChain chain) {
        System.out.println(this.getClass().getSimpleName() + "之前...");
        chain.doFilter(req, resp);
        System.out.println(this.getClass().getSimpleName() + "之后...");
    }
}
public class Filter02 implements Filter{
    @Override
    public void doFilter(Request req, Response resp, FilterChain chain) {
        System.out.println(this.getClass().getSimpleName() + "之前...");
        chain.doFilter(req, resp);
        System.out.println(this.getClass().getSimpleName() + "之后...");
    }
}
  • 过滤器链
/**
 * 过滤器链
 */
public class FilterChain {
	// 所有的具体处理器
    List<Filter> chain = new ArrayList<>();
   	// 调用下标
    private int index = 0;

    // 过滤器链中添加过滤器
    public FilterChain addFilter(Filter filter) {
        chain.add(filter);
        // 方便链式调用
        return this;
    }

    public void doFilter(Request req, Response resp) {
        if (index == chain.size()) {
            return;
        }
        Filter filter = chain.get(index);
        // 在下次调用之前 下标自增
        index++;
        filter.doFilter(req, resp, this);
    }
}
  • 客户端
public class Client {
    public static void main(String[] args) {
        FilterChain filterChain = new FilterChain();
        Filter01 filter01 = new Filter01();
        Filter02 filter02 = new Filter02();
		// 创建过滤器链
        filterChain.addFilter(filter01).addFilter(filter02);

        Request req = null;
        Response resp = null;
        filterChain.doFilter(req, resp);
    }
}
  • 运行结果

Filter01之前…
Filter02之前…
Filter02之后…
Filter01之后…

责任链的优缺点

  • 优点
    • 降低客户端与处理器之前的耦合度
    • 增加可扩展性,只需添加新的处理器并实现抽象处理器接口,客户连接链
    • 单一职责
  • 缺点
    • 不能保证请求一定处理
    • 系统性能会受到一定影响
    • 增加的客户端的复杂度,可能会出现循环调用等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值