其他分享
首页 > 其他分享> > 用最最通俗易懂的例子来谈责任链模式

用最最通俗易懂的例子来谈责任链模式

作者:互联网

责任链模式是什么呢?

责任链模式就是多个处理对象连成链处理单个请求,可能每个处理对象都处理,也可能都不处理。如果要用代码来说就是一个接口,多个实现类而这些处理方式链接成链,诶这就是责任链模式!


用两个例子来深刻理解责任链模式

第一个例子就是请假流程,来瞅瞅流程图

在这里插入图片描述

申请人实体类

/**
 * @author: tianjx
 * @date: 2022/1/13 20:58
 * @description: 请假申请人
 */
public class Leave {
    // 请假人姓名
    private String name;
    // 请假天数
    private int days;

    public Leave() {
    }

    public Leave(String name, int days) {
        this.name = name;
        this.days = days;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

    @Override
    public String toString() {
        return "Leave{" +
                "name='" + name + '\'' +
                ", days='" + days + '\'' +
                '}';
    }
}

处理抽象类(包含设置下一个人的方法)

/**
 * @author: tianjx
 * @date: 2022/1/13 21:00
 * @description: 请假审批抽象类
 */
public abstract class LeaveHandler {
    // 需要总经理批准的审批天数
    protected int MANAGER_LEAVE_DAYS = 3;

    // 领导名称
    private String name;
    // 审批意见
    private boolean approved;
    // 下一个审批人
    protected LeaveHandler nextLeaveHandler;

    // 需要子类实现的具体方法
    public abstract void handle(Leave request);

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean getApproved() {
        return approved;
    }

    public void setApproved(boolean approved) {
        this.approved = approved;
    }

    public LeaveHandler getNextLeaveHandler() {
        return nextLeaveHandler;
    }

    public LeaveHandler setNextLeaveHandler(LeaveHandler nextLeaveHandler) {
        this.nextLeaveHandler = nextLeaveHandler;
        return nextLeaveHandler;
    }

    public int getMANAGER_LEAVE_DAYS(){
        return MANAGER_LEAVE_DAYS;
    }

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

项目经理处理类

/**
 * @author: tianjx
 * @date: 2022/1/13 21:09
 * @description: 项目经理审批
 */
public class ProjectManagerHandler extends LeaveHandler{

    public ProjectManagerHandler(String name){
        super(name);
    }

    @Override
    public void handle(Leave request) {
        if (this.getApproved() == true){
            System.out.println(this.getName() + "审批通过!" + request.toString());
            if (this.nextLeaveHandler != null){
                this.nextLeaveHandler.handle(request);
            }
        }else{
            System.out.println(this.getName() + "审批拒绝!" + request.toString());
        }

    }
}

项目总监处理类

/**
 * @author: tianjx
 * @date: 2022/1/13 21:14
 * @description: 项目总监审批
 */
public class ProjectDirectorHandler extends LeaveHandler{
    public ProjectDirectorHandler(String name){
        super(name);
    }

    @Override
    public void handle(Leave request) {
        if (this.getApproved() == true){
            System.out.println(this.getName() + "审批通过!" + request.toString());
            if (this.nextLeaveHandler != null && request.getDays() > this.getMANAGER_LEAVE_DAYS()){
                this.nextLeaveHandler.handle(request);
            }
        }else{
            System.out.println(this.getName() + "审批拒绝!" + request.toString());
        }

    }
}

总经理处理类

/**
 * @author: tianjx
 * @date: 2022/1/13 21:17
 * @description: 总经理审批
 */
public class MangerLeaveHandler extends LeaveHandler{
    public MangerLeaveHandler(String name){
        super(name);
    }

    @Override
    public void handle(Leave request) {
        if (this.getApproved() == true){
            System.out.println(this.getName() + "审批通过!" + request.toString());
            if (this.nextLeaveHandler != null){
                this.nextLeaveHandler.handle(request);
            }
        }else{
            System.out.println(this.getName() + "审批拒绝!" + request.toString());
        }

    }
}

测试demo

/**
 * @author: tianjx
 * @date: 2022/1/13 21:18
 * @description:
 */
public class LeaveDemo {
    public static void main(String[] args) {
        Leave zs = new Leave("张三",4);
        Leave ls = new Leave("李四",2);
        ProjectManagerHandler projectManagerHandler = new ProjectManagerHandler("项目经理");
        ProjectDirectorHandler projectDirectorHandler = new ProjectDirectorHandler("项目总监");
        MangerLeaveHandler mangerLeaveHandler = new MangerLeaveHandler("总经理");

        // 设置责任链
        projectManagerHandler.setNextLeaveHandler(projectDirectorHandler).setNextLeaveHandler(mangerLeaveHandler);

        projectManagerHandler.setApproved(true);
        projectDirectorHandler.setApproved(true);
        mangerLeaveHandler.setApproved(false);
        projectManagerHandler.handle(zs);

        System.out.println("---------------------------");

        projectManagerHandler.setApproved(true);
        projectDirectorHandler.setApproved(false);
        projectManagerHandler.handle(ls);

    }
}

在这里插入图片描述


第二个例子就是支付金额例子

如果支付金额小于200,免密支付

201-10000,支付密码

10001-100000,短信验证

100001以上扫脸支付!


订单金额实体类

/**
 * @author: tianjx
 * @date: 2022/1/13 21:49
 * @description: 订单实体类
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Order {
    private BigDecimal amount;
}

责任链管理类

/**
 * @author: tianjx
 * @date: 2022/1/13 21:59
 * @description: 责任链管理器
 */
@Component
public class FilterChain implements ApplicationContextAware, PaymentHandler {

    // 存储所有的处理器
    List<PaymentHandler> paymentHandlerList;

    @Override
    public int getIndex() {
        return 0;
    }

    @Override
    public void doFilter(Order order, FilterChain filterChain,Integer count) {
        count = count + 1;
        if (count <= paymentHandlerList.size()){
            paymentHandlerList.get(count - 1).doFilter(order, filterChain, count);
        }else{
            System.out.println("免密支付!");
        }

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, PaymentHandler> handlerMap = applicationContext.getBeansOfType(PaymentHandler.class);// 获取所有的处理器
        paymentHandlerList = new ArrayList<>(handlerMap.values());
        paymentHandlerList = paymentHandlerList.stream()
                .sorted(Comparator.comparing(PaymentHandler::getIndex))// 根据index排序
                .collect(Collectors.toList());// 转换成集合
    }
}

责任链接口

/**
 * @author: tianjx
 * @date: 2022/1/13 21:52
 * @description: 订单金额接口
 */
@Component
public interface PaymentHandler {


    int getIndex();

    /**
     *
     * @param order 订单实体类
     * @param filterChain  责任链管理器
     * @param count 根据index来判断执行了几个
     */
    void doFilter(Order order,FilterChain filterChain,Integer count);
}

责任链实现类

/**
 * @author: tianjx
 * @date: 2022/1/13 21:54
 * @description: 密码支付
 */
@Component
public class MmPaymentHandler implements PaymentHandler {
    @Override
    public int getIndex() {
        return 1;
    }

    @Override
    public void doFilter(Order order, FilterChain filterChain, Integer count) {
        if (order.getAmount().compareTo(BigDecimal.valueOf(201)) == 1 && order.getAmount().compareTo(BigDecimal.valueOf(10000)) == -1){
            System.out.println("请输入密码!");
            return;
        }
        filterChain.doFilter(order, filterChain, count);
    }

}

/**
 *
 * @author: tianjx
 * @date: 2022/1/13 22:15
 * @description:
 */
@Component
public class SmsPaymentHandler implements PaymentHandler{
    @Override
    public int getIndex() {
        return 2;
    }

    @Override
    public void doFilter(Order order, FilterChain filterChain, Integer count) {
        if (order.getAmount().compareTo(BigDecimal.valueOf(10001)) == 1 && order.getAmount().compareTo(BigDecimal.valueOf(100000)) == -1){
            System.out.println("短信验证码支付!");
            return;
        }
        filterChain.doFilter(order, filterChain, count);
    }
}

/**
 * @author: tianjx
 * @date: 2022/1/13 22:18
 * @description:
 */
@Component
public class FacePaymentHandler implements PaymentHandler{
    @Override
    public int getIndex() {
        return 3;
    }

    @Override
    public void doFilter(Order order, FilterChain filterChain, Integer count) {
        if (order.getAmount().compareTo(BigDecimal.valueOf(100001)) == 1){
            System.out.println("请刷脸支付!");
            return;
        }
        filterChain.doFilter(order, filterChain, count);
    }
}

测试demo

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    FilterChain filterChain;

    @Test
    void testChain(){
        Order order1 = new Order(BigDecimal.valueOf(99));
        Order order2 = new Order(BigDecimal.valueOf(299));
        Order order3 = new Order(BigDecimal.valueOf(19988));
        Order order4 = new Order(BigDecimal.valueOf(119988));

        filterChain.doFilter(order1, filterChain, 0);
        filterChain.doFilter(order2, filterChain, 0);
        filterChain.doFilter(order3, filterChain, 0);
        filterChain.doFilter(order4, filterChain, 0);


    }

}

在这里插入图片描述


谈谈责任链模式的优缺点及总结

优点的话,不用说朋友们就知道我要说啥了,从设计原则(设计原则看这篇就够了)上说,因为每个实现类的职责明确且单一所以符合单一职责原则,我们也是面向接口编程,符合依赖倒置原则,而且我们设计接口也是尽量小而精所以也符合接口隔离原则,如果我们添加新的需求只要扩展类就行了,源代码改动比较小也符合开闭原则,这这这应该很棒棒了!

缺点的话,其实如果不懂责任链模式的话其他人来看还是有点生涩的,并且有时候重写接口的话所有子类可能都要修改!

总结一下,责任链模式其实比较常用,我们用的spring的过滤器,拦截器都用到了责任链模式,如果有类似过滤器,请假,金额大小的例子我们可以尝试应用一下!



感谢大家的阅读,我是Alson_Code

标签:最最,return,name,void,通俗易懂,order,public,filterChain,来谈
来源: https://blog.csdn.net/weixin_42415173/article/details/122484586