设计模式之责任链模式

责任链模式

概述

首先我们了解一下什么是“推卸责任”,假设去某购物网站咨询售后问题,首先售前客服会让你联系售后客服,连续售后客服后会让你联系产品质量客服等等,就像被踢皮球一样踢来踢去。推卸责任有点贬义词的意思,但这有利于我们更快的理解责任链模式。

在责任链模式中,每一个处理人只负责它可以处理的问题,如果这个问题处理不了,则推给下一个人,下一个人再处理不了再推给下下个人…这就是责任链模式。

示例程序

在此章节中,我们举一个更贴近生活的例子,公司采购某产品,需要经过3级领导审批,如果价格大于1000块,还需要经过2级领导审批,如果价格大于10000块,还需要1级领导审批。

在这里插入图片描述

基础代码

AuthService作为一个审核服务类,将审核的数据存入到map中

public class AuthService {
   private static Map<String, Date> map = new HashMap<>();

   public static Date queryAuthInfo(String uId,String orderId){
       return map.get(uId.concat(orderId));
   }

   public static void setAuthInfo(String uId,String orderId){
       map.put(uId.concat(orderId),new Date());
   }
}

返回类

@Data
public class AuthInfo {

    private String code;
    private String info = "";

    public AuthInfo(String code, String ...infos) {
        this.code = code;
        for (String str:infos){
            this.info = this.info.concat(str);
        }
    }

}

不使用设计模式实现

将三层审批写在同一个方法中,虽然可以实现对应的功能,但是不遵循开闭原则,对修改很不方便

@Slf4j
public class AuthController {
    public AuthInfo doAuth(String uId,String orderId,Integer authInt){
        //三级审批
        Date date = AuthService.queryAuthInfo("10003", orderId);
        if (date == null){
            return new AuthInfo("0001", "单号:", orderId, " 状态:待三级审批负责人 ", "王工");
        }

        //二级审批
        if (authInt > 1000){
            date = AuthService.queryAuthInfo("10002", orderId);
            if (date == null){
                return new AuthInfo("0001", "单号:", orderId, " 状态:待二级审批负责人 ", "张副总");
            }
        }

        //一级审批
        if (authInt > 10000){
            date = AuthService.queryAuthInfo("10001", orderId);
            if (date == null){
                return new AuthInfo("0001", "单号:", orderId, " 状态:待一级审批负责人 ", "明总");
            }
        }

        //审批完成
        return new AuthInfo("0001", "单号:", orderId, " 状态:审批完成");
    }
}

使用责任链模式

首先定义一个责任链表,所有的审批节点继承该类

public abstract class AuthLink {
    protected String levelUserId; //级别人员id
    protected String levelUserName; //级别人员名称
    private AuthLink next; //下一级别人——责任链

    public AuthLink(String levelUserId, String levelUserName) {
        this.levelUserId = levelUserId;
        this.levelUserName = levelUserName;
    }

    public AuthLink getNext(){
        return next;
    }

    public AuthLink append(AuthLink next){
        this.next = next;
        return this;
    }

    public abstract AuthInfo doAuth(String uId,String orderId,int authInt);
}

三层审批节点

//三级领导审批
public class Level3Auth extends AuthLink {
    public Level3Auth(String levelUserId, String levelUserName) {
        super(levelUserId, levelUserName);
    }

    @Override
    public AuthInfo doAuth(String uId, String orderId, int authInt) {
        Date date = AuthService.queryAuthInfo("10003", orderId);
        if (null == date){
            return new AuthInfo("0001", "单号:", orderId, " 状态:待三级审批负责人 ", levelUserName);
        }
        AuthLink next = super.getNext();
        if (null == next){
            return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批完成负责人", " 时间:", date.toString(), " 审批人:", levelUserName);
        }

        if (authInt <= 1000){
            return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批负责人完成", " 时间:", date.toString(), " 审批人:", levelUserName);
        }
        return next.doAuth(uId,orderId,authInt);
    }
}

//二级领导审批
public class Level2Auth extends AuthLink {
    public Level2Auth(String levelUserId, String levelUserName) {
        super(levelUserId, levelUserName);
    }

    @Override
    public AuthInfo doAuth(String uId, String orderId, int authInt) {
        Date date = AuthService.queryAuthInfo("10002", orderId);
        if (null == date){
            return new AuthInfo("0001", "单号:", orderId, " 状态:待二级审批负责人 ", levelUserName);
        }
        AuthLink next = super.getNext();
        if (null == next){
            return new AuthInfo("0000", "单号:", orderId, " 状态:二级审批完成负责人", " 时间:", date.toString(), " 审批人:", levelUserName);
        }

        if (authInt > 1000 && authInt <= 10000){
            return new AuthInfo("0000", "单号:", orderId, " 状态:二级审批完成负责人", " 时间:", date.toString(), " 审批人:", levelUserName);
        }
        return next.doAuth(uId,orderId,authInt);
    }
}

//一级领导审批
public class Level1Auth extends AuthLink {
    public Level1Auth(String levelUserId, String levelUserName) {
        super(levelUserId, levelUserName);
    }

    @Override
    public AuthInfo doAuth(String uId, String orderId, int authInt) {
        Date date = AuthService.queryAuthInfo("10001", orderId);
        if (null == date){
            return new AuthInfo("0001", "单号:", orderId, " 状态:待一级审批负责人 ", levelUserName);
        }
        AuthLink next = super.getNext();
        if (null == next){
            return new AuthInfo("0000", "单号:", orderId, " 状态:一级审批完成负责人", " 时间:", date.toString(), " 审批人:", levelUserName);
        }

        return next.doAuth(uId,orderId,authInt);
    }
}

测试

@SpringBootTest
@Slf4j
class Practice1602ApplicationTests {
    @Test
    void contextLoads() {
        AuthLink authLink = new Level3Auth("10003","王工")
                .append(new Level2Auth("10002","张副总")
                                .append(new Level1Auth("10001","明总")));
        log.info(authLink.doAuth("yellowstar", "1300909091", 10001).toString());

        log.info("模拟三级负责人审批");
        AuthService.setAuthInfo("10003","1300909091");
        log.info(authLink.doAuth("yellowstar", "1300909091", 10001).toString());

        log.info("模拟二级负责人审批");
        AuthService.setAuthInfo("10002","1300909091");
        log.info(authLink.doAuth("yellowstar", "1300909091", 10001).toString());

        log.info("模拟一级负责人审批");
        AuthService.setAuthInfo("10001","1300909091");
        log.info(authLink.doAuth("yellowstar", "1300909091", 10001).toString());
    }
}

//结果
//AuthInfo(code=0001, info=单号:1300909091 状态:待三级审批负责人 王工)
//模拟三级负责人审批
//AuthInfo(code=0001, info=单号:1300909091 状态:待二级审批负责人 张副总)
//模拟二级负责人审批
//AuthInfo(code=0001, info=单号:1300909091 状态:待一级审批负责人 明总)
//模拟一级负责人审批
//AuthInfo(code=0000, info=单号:1300909091 状态:一级审批完成负责人 时间:Mon Jun 20 17:11:44 CST 2022 审批人:明总)

总结

责任链模式弱化了发出请求的人和处理请求的人之间的关系,如果不适用该模式,就必须有某个伟大的角色知道谁该处理当前请求,有点类似于中央集权制。

责任链模式很好的处理单一职责和开闭原则,简单了耦合也使对象关系更加清晰,而外部的调用方不需要关心责任链使如何进行处理的。但除了这些优点外也需要是适当的场景才进行使用,避免造成性能以及编排混乱调试测试疏漏问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值