设计模式从入门到放弃(二十二)责任链模式

基本介绍

责任链模式 Chain of Responsibility Pattern 为请求创建一个接受者对象者链,将请求的发送者和接受者解耦。每个接受者都包含一个下一个接受者的引用,如果当前接受者不能处理的请求则会转发给下一个接受者。

UML

在这里插入图片描述

角色分析

Request 请求 包装多个请求的参数

Handler 责任链抽象类 组合了下一个责任链 包含一个handler 的抽象方法

ConcreteHandlerChain 责任链具体实现

Client 责任链调用者也需要将责任链串联起来

代码演示

典型的场景就是财务审核,0-2000部门经理审核,2000-5000CTO审核,5000以上Boss审核,这样的需求非常合适责任链模式设计

// Requst 请求 包装了所有在责任链中处理需要的参数
@Data
public class Request {

    private final String name;

    private final float money;

    public Request(String name, float money) {
        this.name = name;
        this.money = money;
    }
}
// 抽象责任链
public abstract class HandlerChain {
	// 下一个责任链
    protected HandlerChain nextChain;

    public HandlerChain getNextChain() {
        return nextChain;
    }

    public void setNextChain(HandlerChain nextChain) {
        this.nextChain = nextChain;
    }
	// 抽象处理方法
    public abstract void handler(Request request);
}


public class DeptManagerHandlerChain extends HandlerChain {

    private final String name;

    public DeptManagerHandlerChain( String name) {
        this.name = name;
    }

    @Override
    public void handler(Request request) {
        // 处理0-2000
        if (request.getMoney() > 0 && request.getMoney() <= 2000.0) {
            System.out.println(name + "处理了" + request.getName() + "的" + request.getMoney() + "元的请求!");
        }else{
            getNextChain().handler(request);
        }
    }
}
public class CTOHandlerChain extends HandlerChain {

    private final String name;

    public CTOHandlerChain(String name) {
        this.name = name;
    }

    @Override
    public void handler(Request request) {
        if (request.getMoney() > 2000 && request.getMoney() <= 5000.0) {
            System.out.println(name + "处理了" + request.getName() + "的" + request.getMoney() + "元的请求!");
        } else {
            nextChain.handler(request);
        }
    }
}

public class BossHandlerChain extends HandlerChain {

    private final String name;

    public BossHandlerChain(String name) {
        this.name = name;
    }

    @Override
    public void handler(Request request) {
        if (request.getMoney() > 5000) {
            System.out.println(name + "处理了" + request.getName() + "的" + request.getMoney() + "元的请求!");
        } else {
            nextChain.handler(request);
        }
    }
}

// 调用测试
public class HandlerChainTest {
    public static void main(String[] args) {
        Request request = new Request("小王", 22220);
        DeptManagerHandlerChain deptManagerHandlerChain = new DeptManagerHandlerChain("王部门经理");
        CTOHandlerChain ctoHandlerChain = new CTOHandlerChain("张CTO");
        BossHandlerChain bossHandlerChain = new BossHandlerChain("赵Boss");
        // 设置部门经理下一个CTO
        deptManagerHandlerChain.setNextChain(ctoHandlerChain);
        // CTO --> BOSS
        ctoHandlerChain.setNextChain(bossHandlerChain);
        // BOSS--> 部门经理 形成闭环
        bossHandlerChain.setNextChain(deptManagerHandlerChain);
        deptManagerHandlerChain.handler(request);
    }
}

使用细节

  • 请求和处理请求分开,实现解耦,提高系统灵活性
  • 简化使用,调用者无需知道责任链的内部结构
  • 缺点在于如果责任链特别长会增加性能损耗,可以在责任链中控制最大节点数,一般在Handler中设置最大节点数,在setNext方法之前判断是否已经超过阈值,超过则不允许创建,避免过长链损耗系统性能
  • 最佳使用场景 请假 审批等流程请求 拦截器等

猜你喜欢

转载自blog.csdn.net/woshiwjma956/article/details/106136391
今日推荐