Skip to content

设计模式框架

更新: 12/4/2025 字数: 0 字 时长: 0 分钟

Maven

1. 规则树

1.1. 简介

解耦业务逻辑与流程流转,将特定业务代码封装成节点,动态组装使用

1.2 优点

  • 避免频繁地编写 if…else 逻辑
  • 可以回到已经走过的节点,实现节点复用

1.3 使用方法

step1: 引入依赖

xml
<dependency>
    <groupId>cn.wanyj.component</groupId>
    <artifactId>design-pattern-framework</artifactId>
    <version>1.0.0</version>
</dependency>

step2: 根据需求,自定义上下文实体

java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DynamicContext {
    private int sum;

    private Map<String, Object> dataObjects = new HashMap<>();

    public <T> void setValue(String key, T value) {
        dataObjects.put(key, value);
    }

    public <T> T getValue(String key) {
        return (T) dataObjects.get(key);
    }
}

step3: 自定义抽象类继承AbstractMultiThreadStrategyRouter<T, D, R>

java
public abstract class AbstractXxxSupport extends AbstractMultiThreadStrategyRouter<入参, 上下文实体, 出参> {
    
}

step4: 编写各个节点,并继承自定义的抽象类,重写doApplygetNext方法,如果有数据要加载,重写multiThread方法

java
@Slf4j
@Component
public class Node1 extends AbstractXxxSupport {

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Resource
    private Node2_1 node2_1;

    @Resource
    private Node2_2 node2_2;
    
    @Override
    protected void multiThread(String userId, DynamicContext dynamicContext) {
        CompletableFuture<Integer> mock1 = CompletableFuture.supplyAsync(() -> {
            log.info("线程1加载数据");
            return new Random().nextBoolean() ? 1 : 2;
        }, threadPoolExecutor);

        CompletableFuture<Integer> mock2 = CompletableFuture.supplyAsync(() -> {
            log.info("线程2加载数据");
            return new Random().nextBoolean() ? 1 : 2;
        }, threadPoolExecutor);

        CompletableFuture.allOf(mock1, mock2)
                .thenRun(() -> {
                    dynamicContext.setValue("mock1", mock1.join());
                    dynamicContext.setValue("mock2", mock2.join());
                }).join();
    }

    @Override
    protected String doApply(String userId, DynamicContext dynamicContext) {
        log.info("[Node1]:{}", userId);
        int sum = 3;
        log.info("预期和 sum={}", sum);
        dynamicContext.setSum(sum);
        return router(userId, dynamicContext);
    }

    @Override
    public StrategyHandler<String, DynamicContext, String> getNext(String userId, DynamicContext dynamicContext) {
        int mock1 = dynamicContext.getValue("mock1");
        int mock2 = dynamicContext.getValue("mock2");
        int sum = dynamicContext.getSum();
        log.info("mock1={},mock2={},sum={}", mock1, mock2, sum);
        if (mock1+mock2== sum) {
            log.info("mock1+mock2==sum, 符合预期, 走node2_1节点");
            return node2_1;
        }
        log.info("mock1+mock2!=sum, 不符合预期, 走node2_2节点");
        return node2_2;
    }
}

step5: 指定入口节点

java
@Service
public class DefaultStrategyFactory {

    private final Node1 node1;

    public DefaultStrategyFactory(Node1 node1) {
        this.node1 = node1;
    }

    public StrategyHandler<String, DynamicContext, String> strategyHandler() {
        return node1;
    }
}

step6: 传入参数,执行规则树

java
StrategyHandler<String, DynamicContext, String> strategyHandler = defaultStrategyFactory.strategyHandler();
String result = strategyHandler.apply("1379666", new DynamicContext());

2. 责任链

2.1. 简介

预先组装好责任链节点,符合条件的请求按顺序执行

2.2 优点

  • 拆成有针对性的节点,避免一个类中写大量代码
  • 便于调整先后顺序

2.3 使用方法

step1: 引入依赖

xml
<dependency>
    <groupId>cn.wanyj.component</groupId>
    <artifactId>design-pattern-framework</artifactId>
    <version>1.0.0</version>
</dependency>

step2: 根据需求,自定义上下文实体,并继承ProceedDynamicContext

java
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class DynamicContext extends ProceedDynamicContext{
    private int sum;

    private Map<String, Object> dataObjects = new HashMap<>();

    public <T> void setValue(String key, T value) {
        dataObjects.put(key, value);
    }

    public <T> T getValue(String key) {
        return (T) dataObjects.get(key);
    }
}

step3: 编写各个节点,并实现ChainHandler<T, D extends ProceedDynamicContext, R>接口

  • next(T request, D dynamicContext) 继续执行下一个节点
  • stop(T request, D dynamicContext, R result) 停止执行,返回当前结果
java
@Slf4j
@Component
public class ChainNode1 implements ChainHandler<入参, 上下文实体, 出参> {
    @Override
    public String apply(String userId, DynamicContext dynamicContext) {
        log.info("[ChainNode1]");
        return next(userId, dynamicContext);
    }
}

step5: 组装责任链

java
@Service
public class DefaultChainFactory {
    @Bean
    public BusinessLinkedList<String, DynamicContext, String> d1(ChainNode1 node1, ChainNode2 node2){
        ChainArmory<String, DynamicContext, String> chainArmory = new ChainArmory<>("d1", node1, node2);
        return chainArmory.getBusinessLinkedList();
    }
}

step6: 传入参数,执行责任链

java
@Resource
private BusinessLinkedList<String, DynamicContext, String> businessLinkedList;
String result = businessLinkedList.apply("1379666", new DynamicContext());

©2025 YONG. All rights reserved.

本站访客数 人次 本站总访问量