2.1.责任链模式

在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

JDK中的使用

  • java.util.logging.Logger#log(java.util.logging.LogRecord)
  • javax.servlet.Filter#doFilter()
  • dubbo、motan中的filter链

代码实现

在公司申请经费在一定金额限制下分别可以由leader、manager、boss同意

// 申请请求
@Data
public class HandleRequest {
    /**
     * 活动主体
     */
    private String activityTheme;
    /**
     * 申请活动资金
     */
    private BigDecimal activityCapital;
}
// 申请结果
@Data
@Builder
public class HandleResult {
    private Boolean isOk;
    private String from;
    private String result;

    public static HandleResult ok(String from, String result){
        return HandleResult.builder()
            .isOk(Boolean.TRUE)
            .from(from)
            .result(result)
            .build();
    }

    public static HandleResult reject(String from, String result){
        return HandleResult.builder()
            .isOk(Boolean.FALSE)
            .from(from)
            .result(result)
            .build();
    }
}

public interface Handler {
    HandleResult handle(HandleRequest request);
}
public abstract class AbstractHandler implements Handler {
    @Getter
    private Handler superior;

    public AbstractHandler() {

    }

    public AbstractHandler(Handler superior) {
        this.superior = superior;
    }

    /**
     * 职位名称
     * @return 职位名称
     */
    protected abstract String getPosition();

    /**
     * 当前是否能审批
     * @param request 请求
     * @return true/能 false/不能
     */
    protected abstract boolean canApprove(HandleRequest request);

    @Override
    public HandleResult handle(HandleRequest request) {
        if (this.canApprove(request)) {
            return HandleResult.ok(this.getPosition(), request.getActivityTheme() + " ok");
        }

        return this.superior != null
            ? this.superior.handle(request)
            : HandleResult.reject(this.getPosition(), request.getActivityTheme() + " reject");
    }
}
public class Leader extends AbstractHandler {
    public Leader(){
        super();
    }

    public Leader(Handler handler){
        super(handler);
    }
    @Override
    protected String getPosition() {
        return "leader";
    }
    @Override
    protected boolean canApprove(HandleRequest request) {
        // leader只能审批100元及以下的金额
        return request.getActivityCapital().compareTo(new BigDecimal("100")) <= 0;
    }
}
public class Manager extends AbstractHandler {
    public Manager(){
        super();
    }

    public Manager(Handler handler){
        super(handler);
    }

    @Override
    protected String getPosition() {
        return "manager";
    }

    @Override
    protected boolean canApprove(HandleRequest request) {
        // manager只能审批500元及以下的金额
        return request.getActivityCapital().compareTo(new BigDecimal("500")) <= 0;
    }
}
public class Boss extends AbstractHandler {
    public Boss(){
        super();
    }

    public Boss(Handler handler){
        super(handler);
    }

    @Override
    protected String getPosition() {
        return "boss";
    }

    @Override
    protected boolean canApprove(HandleRequest request) {
        // boss只同意1000元及以下金额
        return request.getActivityCapital().compareTo(new BigDecimal("1000")) <= 0;
    }
}

单元测试

class AbstractHandlerSpec extends Specification {
    def leader() {
        given:
        def leader = new Leader()
        def handleResult = leader.handle(new HandleRequest(activityTheme: activityTheme, activityCapital: activityCapital))
        expect:
        handleResult.getIsOk() == isOk
        handleResult.getFrom() == fromPosition
        handleResult.getResult() == resultMessage

        where:
        activityCapital       | activityTheme || fromPosition || resultMessage || isOk
        new BigDecimal("100") | "团建"          || "leader"     || "团建 ok"       || Boolean.TRUE
        new BigDecimal("101") | "ktv"         || "leader"     || "ktv reject"  || Boolean.FALSE
    }

    def manager() {
        given:
        def manager = new Manager()
        def leader = new Leader(manager)
        def handleResult = leader.handle(new HandleRequest(activityTheme: activityTheme, activityCapital: activityCapital))
        expect:
        handleResult.getIsOk() == isOk
        handleResult.getFrom() == fromPosition
        handleResult.getResult() == resultMessage

        where:
        activityCapital       | activityTheme || fromPosition || resultMessage || isOk
        new BigDecimal("100") | "团建"          || "leader"     || "团建 ok"       || Boolean.TRUE
        new BigDecimal("101") | "ktv"         || "manager"    || "ktv ok"      || Boolean.TRUE
        new BigDecimal("499") | "乒乓球"         || "manager"    || "乒乓球 ok"      || Boolean.TRUE
        new BigDecimal("501") | "室内篮球"        || "manager"    || "室内篮球 reject" || Boolean.FALSE
    }

    def boss() {
        given:
        def boss = new Boss()
        def manager = new Manager(boss)
        def leader = new Leader(manager)
        def handleResult = leader.handle(new HandleRequest(activityTheme: activityTheme, activityCapital: activityCapital))
        expect:
        handleResult.getIsOk() == isOk
        handleResult.getFrom() == fromPosition
        handleResult.getResult() == resultMessage

        where:
        activityCapital        | activityTheme || fromPosition || resultMessage || isOk
        new BigDecimal("100")  | "团建"          || "leader"     || "团建 ok"       || Boolean.TRUE
        new BigDecimal("101")  | "ktv"         || "manager"    || "ktv ok"      || Boolean.TRUE
        new BigDecimal("499")  | "乒乓球"         || "manager"    || "乒乓球 ok"      || Boolean.TRUE
        new BigDecimal("501")  | "室内篮球"        || "boss"       || "室内篮球 ok"     || Boolean.TRUE
        new BigDecimal("1000") | "旅游"          || "boss"       || "旅游 ok"       || Boolean.TRUE
        new BigDecimal("1001") | "显卡"          || "boss"       || "显卡 reject"   || Boolean.FALSE
    }
}