设计模式框架
更新: 12/4/2025 字数: 0 字 时长: 0 分钟
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: 编写各个节点,并继承自定义的抽象类,重写doApply和getNext方法,如果有数据要加载,重写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());
