责任链模式

步骤1:定义一个接口,用于责任链装配

public interface IActionChainArmory {

    IActionChain next();

    IActionChain appendNext(IActionChain next);

}

步骤2:定义责任链接口,继承装配接口

public interface IActionChain extends IActionChainArmory {

    boolean action(Integer input);

}

步骤3:定义抽象类,实现责任链接口

public abstract class AbstractActionChain implements IActionChain {

    private IActionChain next;

    @Override
    public IActionChain next() {
        return next;
    }

    @Override
    public IActionChain appendNext(IActionChain next) {
        this.next = next;
        return next;
    }

}

步骤4:行为实现类,继承抽象类

@Component("normal_action")
public class NormalActionChain extends AbstractActionChain {

    @Override
    public boolean action(Integer input) {
        // 校验
        if (input == 0) {
            return false;
        }
        return next().action(input);
    }

}

@Component("last_action")
public class LastActionChain extends AbstractActionChain {

    @Override
    public boolean action(Integer input) {
        // 需要配置一个最后一环来处理最终逻辑
        return true;
    }

}

步骤5:工厂类装配责任链

固定流程责任链

如果责任链流程固定,可以直接再构造函数中组装

@Service
public class DefaultActivityChainFactory {

    private final IActionChain actionChain;

    /**
     * 1. 通过构造函数注入。
     * 2. Spring 可以自动注入 IActionChain 接口实现类到 map 对象中,key 就是 bean 的名字。
     */
    public DefaultActivityChainFactory(Map<String, IActionChain> actionChainGroup) {
        actionChain = actionChainGroup.get(ActionModel.NORMAL_ACTION.code);
        actionChain.appendNext(actionChainGroup.get(ActionModel.LAST_ACTION.getCode()));
    }

    public IActionChain openActionChain() {
        return this.actionChain;
    }

    @Getter
    @AllArgsConstructor
    public enum ActionModel {

        NORMAL_ACTION("normal_action", "某一环处理逻辑"),
        LAST_ACTION("last_action", "最终处理逻辑"),
        ;

        private final String code;
        private final String info;

    }

}

动态建链

如果流程需要动态决定,则需要把责任链定义为原型模式,客户调用时,根据动态规则从applicationContext获取bean。组装完成后可以把流程存放在ConcurrentHashMap中,下次就不用动态建链。

@Component("normal_action")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) // scope为原型模式
public class FirstActionChain extends AbstractActionChain {
    // 具体实现
}
@Service
public class DefaultChainFactory {
    // 原型模式获取对象
    private final ApplicationContext applicationContext;
    // 存放策略链,策略ID -> 责任链
    private final Map<Long, ILogicChain> strategyChainGroup;

    public DefaultChainFactory(ApplicationContext applicationContext, IStrategyRepository repository) {
        this.applicationContext = applicationContext;
        this.strategyChainGroup = new ConcurrentHashMap<>();
    }

    /**
     * 根据input,决定责任链流程
     * @param input 策略ID
     * @return LogicChain
     */
    public ILogicChain openLogicChain(Long input) {
        // 根据业务获取处理流程
        String[] ruleModels = getRuleModels();
        // 按照配置顺序装填用户配置的责任链
        ILogicChain logicChain = applicationContext.getBean(ruleModels[0], ILogicChain.class);
        ILogicChain current = logicChain;
        for (int i = 1; i < ruleModels.length; i++) {
            ILogicChain nextChain = applicationContext.getBean(ruleModels[i], ILogicChain.class);
            current = current.appendNext(nextChain);
        }

        // 责任链的最后装填默认责任链
        current.appendNext(applicationContext.getBean(LogicModel.LAST_ACTION.getCode(), ILogicChain.class));
        // 写入缓存
        strategyChainGroup.put(input, logicChain);

        return logicChain;
    }

    @Getter
    @AllArgsConstructor
    public enum LogicModel {

        NORMAL_ACTION("normal_action", "某一环处理逻辑"),
        LAST_ACTION("last_action", "最终处理逻辑"),
        ;

        private final String code;
        private final String info;
    }
}
posted @ 2025-07-11 15:58  庚申码上仙  阅读(10)  评论(0)    收藏  举报