设计模式-行为型-责任链模式

128 阅读3分钟

定义

「大话设计模式」之职责链模式定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

这里发出请求的客户端并不知道这当中哪一个对象最终处理这个请求,这样系统的更改可以在不影响客户端的情况下动态的重新组织和分配责任。

实战

背景:一般请假,如果天数很多,那么会涉及到公司高层审批。

抽象类

定义一个抽象类,里面有一个模板方法,具体的实现类都会实现这个模板方法(类似 StringBuilder#append 会放回当前对象)

public abstract class AuthLink {
    protected Logger logger = LoggerFactory.getLogger(AuthLink.class);
    protected SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 时间格式化
    protected String levelUserId; // 级别⼈人员ID
    protected String levelUserName; // 级别⼈人员姓名
    private AuthLink next; // 责任链

    public AuthLink(String levelUserId, String levelUserName) {
        this.levelUserId = levelUserId;
        this.levelUserName = levelUserName;
    }
    public AuthLink next() {
        return next;
    }
    public AuthLink appendNext(AuthLink next) {
        this.next = next;
        return this;
    }
    //模板方法
    public abstract AuthInfo doAuth(String uId, String orderId, Date authDate);
}

三级审批

先获取单号的基本信息,如果为空表示这一级还没有审批,需要审批之后才会到下一级。

如果不为空,则要获取下一级处理:进行相应的逻辑判断,下一级为空,表示就到我这就好了,不用更高的领导处理,如果下一级不为空,则会调用下一级的处理方法:next.doAuth(uId, orderId, authDate); 直到可以处理为止。

public class Level3Authlink extends AuthLink{
    private Date beginDate = f.parse("2020-06-01 00:00:00");
    private Date endDate = f.parse("2020-06-25 23:59:59");
    public Level3Authlink(String levelUserId, String levelUserName) throws
            ParseException {
        super(levelUserId, levelUserName);
    }
    public AuthInfo doAuth(String uId, String orderId, Date authDate) {
        Date date = AuthService.queryAuthInfo(levelUserId, orderId);
        if (null == date) {
            return new AuthInfo("0001", "单号:", orderId, " 状态:待三级审批负责人 ", levelUserName);
        }
        
        AuthLink next = super.next();
        if (null == next) {
            return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批负责人完成", " 时间:", f.format(date), " 审批人:", levelUserName);
        }
        if (authDate.before(beginDate) || authDate.after(endDate)) {
            return new AuthInfo("0000", "单号:", orderId, " 状态:三级审批负责人完成", " 时间:", f.format(date), " 审批人:", levelUserName);
        }
        return next.doAuth(uId, orderId, authDate);
    }
}

二级审批和一级审批同理。

测试

对审批链的定义如下:

    AuthLink authLink = new Level3Authlink("1000013", "王工")
                .appendNext(new Level2Authlink("1000012", "张经理")
                        .appendNext(new Level1Authlink("1000011", "段总")));


authLink.doAuth(xxx);

总结

  • 可以解决大量 if-else 代码,设想下,按照一般思路,肯定是 if-else 判断为几级领导再对应处理。
  • 定义的抽象类中有一个方法,和模板方法思想一致,可以将可抽离的公共判断放到这里,然后具体的实现类只需要关注自己的逻辑
  • 我们可以随意的对职责链模式添加节点,但是如果配置不当,处理到末端节点但是还没有解决,所以这也需要我们事先就考虑的比较全面一点。