详细介绍:【设计模式】Java规则树重构复杂业务逻辑
2025-11-16 08:57 tlnshuju 阅读(0) 评论(0) 收藏 举报前言
一、规则树核心概念与设计原理
二、核心代码实现
2.3 AbstractStrategyRouter 策略路由抽象类
2.4 AbstractMultiThreadStrategyRouter 异步资源加载策略抽象类
三、规则树效果测试
3.1 DefaultStrategyFactory 默认策略工厂
3.6 MemberLevelNode1 会员级别1节点策略处理器
3.7 MemberLevelNode2 会员级别2节点策略处理器
四、总结
前言
随着企业数字化转型的深入,业务逻辑变得越来越复杂且多变。以电商平台为例,一个简单的优惠券计算可能涉及数十个条件:用户等级、商品品类、订单金额、促销活动、库存状态、时间周期等。传统的编程方式通常使用大量的if-else或switch-case语句来处理这些规则,导致代码出现以下问题:
代码臃肿:一个方法可能包含数百行的条件判断
难以维护:每次业务规则变更都需要修改代码并重新部署
耦合度高:业务规则与核心逻辑紧密耦合,无法独立变化
可读性差:复杂的嵌套条件让新同事难以理解业务逻辑
测试困难:覆盖所有条件分支需要编写大量测试用例
规则树模式(Rule Tree Pattern) 正是为了解决这些问题而生的。它将复杂的业务规则抽象为树形结构,通过节点之间的组合关系来表达业务逻辑,实现了业务规则与核心流程的解耦,让系统能够快速响应业务变化。
一、规则树核心概念与设计原理
1.1 规则树的基本概念
规则树是一种树形数据结构,用于表示和执行复杂的业务规则。它由以下核心组件构成:
根节点(Root Node):规则的入口点,整个规则树的起点
条件节点(Condition Node):负责评估特定条件,决定执行路径
动作节点(Action Node):执行具体的业务操作或返回结果
组合节点(Composite Node):包含子节点,控制执行逻辑(与、或、非等)
叶子节点(Leaf Node):没有子节点的终端节点,通常是动作节点
1.2 规则树的类型与适用场景
根据不同的业务需求,规则树可以分为多种类型:
| 类型 | 特点 | 适用场景 |
|---|---|---|
| 决策树 | 每个节点代表一个决策点,路径清晰 | 分类问题、风险评估 |
| 行为树 | 关注节点执行和行为控制 | 游戏AI、工作流引擎 |
| 表达式树 | 将数学表达式转化为树结构 | 计算规则、定价引擎 |
| 组合规则树 | 支持复杂的逻辑组合 | 风控系统、合规检查 |
二、核心代码实现
2.1 StrategyHandler 策略处理接口
StrategyHandler 是一个泛型接口,定义了策略处理的核心方法。它包含一个默认实现,当没有匹配的策略时使用默认处理。该接口的泛型参数包括请求参数类型(T)、动态上下文类型(D)和返回结果类型(R)。
/*** @description 受理策略处理* T 入参类型* D 上下文参数* R 返参类型*/
public interface StrategyHandler {StrategyHandler DEFAULT = (T, D) -> null;R apply(T requestParameter, D dynamicContext) throws Exception;
}
2.2 StrategyMapper 策略映射器
StrategyMapper 是一个泛型接口,用于根据请求参数和动态上下文获取待执行的策略处理器。它定义了一个方法,根据传入的参数返回对应的策略处理器。
/*** @description 策略映射器* T 入参类型* D 上下文参数* R 返参类型*/
public interface StrategyMapper {/*** 获取待执行策略** @param requestParameter 入参* @param dynamicContext 上下文* @return 返参* @throws Exception 异常*/StrategyHandler get(T requestParameter, D dynamicContext) throws Exception;
}
2.3 AbstractStrategyRouter 策略路由抽象类
AbstractStrategyRouter 是一个抽象类,结合了策略处理器和策略映射器的功能,提供了灵活的策略路由机制。它实现了 StrategyMapper 和 StrategyHandler 接口,兼具映射和执行能力。该类还提供了一个默认策略处理器,当没有匹配的策略时使用默认处理。
import lombok.Getter;
import lombok.Setter;
/*** 策略路由抽象类* 结合策略处理器和策略映射器的功能,提供灵活的策略路由机制** 功能说明:* 1. 实现策略路由的核心逻辑,根据请求参数和上下文选择合适的策略处理器* 2. 提供默认策略处理器,当没有匹配的策略时使用默认处理* 3. 同时实现StrategyMapper和StrategyHandler接口,兼具映射和执行能力** 泛型参数说明:* - T: 请求参数类型(Request Parameter Type)* - D: 动态上下文类型(Dynamic Context Type)* - R: 返回结果类型(Return Result Type)*/
public abstract class AbstractStrategyRouter implements StrategyMapper, StrategyHandler {/*** 默认策略处理器* 当没有找到匹配的策略处理器时使用该默认处理器* 使用Lombok注解自动生成getter和setter方法*/@Getter@Setterprotected StrategyHandler defaultStrategyHandler = StrategyHandler.DEFAULT;/*** 策略路由方法* 根据请求参数和动态上下文选择合适的策略处理器并执行** @param requestParameter 请求参数* @param dynamicContext 动态上下文,包含执行过程中的共享数据* @return 策略处理器的执行结果* @throws Exception 策略执行过程中可能抛出的异常*/public R router(T requestParameter, D dynamicContext) throws Exception {// 1. 获取匹配的策略处理器StrategyHandler strategyHandler = get(requestParameter, dynamicContext);// 2. 如果找到匹配的策略处理器,则执行该策略if(null != strategyHandler) {return strategyHandler.apply(requestParameter, dynamicContext);}// 3. 如果没有找到匹配的策略,则使用默认策略处理器return defaultStrategyHandler.apply(requestParameter, dynamicContext);}
}
2.4 AbstractMultiThreadStrategyRouter 异步资源加载策略抽象类
bstractMultiThreadStrategyRouter 扩展了基础策略路由,支持多线程异步数据加载和业务处理分离。它提供了异步数据加载框架,在执行业务逻辑前预先加载所需资源,从而提高系统性能和响应速度。
import lombok.Getter;
import lombok.Setter;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/*** 异步资源加载策略路由抽象类* 扩展基础策略路由,支持多线程异步数据加载和业务处理分离** 功能说明:* 1. 提供异步数据加载框架,在执行业务逻辑前预先加载所需资源* 2. 分离数据加载和业务处理,提高系统性能和响应速度* 3. 支持多线程并发执行,优化资源利用率** 泛型参数说明:* - T: 请求参数类型(Request Parameter Type)* - D: 动态上下文类型(Dynamic Context Type)* - R: 返回结果类型(Return Result Type)*/
public abstract class AbstractMultiThreadStrategyRouter implements StrategyMapper, StrategyHandler {/*** 默认策略处理器* 当没有找到匹配的策略处理器时使用该默认处理器*/@Getter@Setterprotected StrategyHandler defaultStrategyHandler = StrategyHandler.DEFAULT;/*** 策略路由方法* 根据请求参数和动态上下文选择合适的策略处理器并执行** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 策略处理器的执行结果* @throws Exception 执行过程中可能抛出的异常*/public R router(T requestParameter, D dynamicContext) throws Exception {// 1. 获取匹配的策略处理器StrategyHandler strategyHandler = get(requestParameter, dynamicContext);// 2. 如果找到匹配的策略处理器,则执行该策略if(null != strategyHandler) {return strategyHandler.apply(requestParameter, dynamicContext);}// 3. 如果没有找到匹配的策略,则使用默认策略处理器return defaultStrategyHandler.apply(requestParameter, dynamicContext);}/*** 策略执行方法(模板方法)* 定义异步加载+业务处理的执行流程** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 业务处理结果* @throws Exception 执行过程中可能抛出的异常*/@Overridepublic R apply(T requestParameter, D dynamicContext) throws Exception {// 第一阶段:异步加载数据(多线程执行)multiThread(requestParameter, dynamicContext);// 第二阶段:业务流程受理(单线程执行)return doApply(requestParameter, dynamicContext);}/*** 异步数据加载方法(抽象方法)* 子类需要实现具体的多线程数据加载逻辑** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @throws ExecutionException 执行异常* @throws InterruptedException 线程中断异常* @throws TimeoutException 超时异常*/protected abstract void multiThread(T requestParameter, D dynamicContext) throws ExecutionException, InterruptedException, TimeoutException;/*** 业务流程处理方法(抽象方法)* 子类需要实现具体的业务逻辑** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 业务处理结果* @throws Exception 业务处理过程中可能抛出的异常*/protected abstract R doApply(T requestParameter, D dynamicContext) throws Exception;
}
三、规则树效果测试
3.1 DefaultStrategyFactory 默认策略工厂
DefaultStrategyFactory 是一个策略工厂类,负责创建和管理策略处理器,提供策略模式的统一入口。它维护策略执行的上下文信息,支持数据在不同策略节点间传递。
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
/*** 默认策略工厂* 负责创建和管理策略处理器,提供策略模式的统一入口** 功能说明:* 1. 作为策略模式的工厂类,提供策略处理器的获取* 2. 维护策略执行的上下文信息,支持数据在不同策略节点间传递* 3. 使用Spring Service注解,作为单例Bean管理*/
@Service
public class DefaultStrategyFactory {// 根节点处理器,作为策略链的起点private final RootNode rootNode;/*** 构造函数,通过依赖注入初始化根节点* @param rootNode 根节点策略处理器*/public DefaultStrategyFactory(RootNode rootNode) {this.rootNode = rootNode;}/*** 获取策略处理器* @return 根节点策略处理器,作为整个策略链的入口*/public StrategyHandler strategyHandler() {return rootNode;}/*** 动态上下文类* 用于在策略执行过程中传递和共享数据** 功能特点:* - 使用泛型支持不同类型的数据存储和获取* - 基于HashMap实现键值对存储* - 支持层级管理(level字段)* - 使用Lombok注解简化代码*/@Data@Builder@AllArgsConstructor@NoArgsConstructorpublic static class DynamicContext {/*** 执行层级,可用于控制策略执行的深度或阶段*/private int level;/*** 数据对象映射表,用于存储策略执行过程中的中间数据*/private Map dataObjects = new HashMap<>();/*** 设置上下文值* @param key 键名* @param value 值(泛型支持任意类型)* @param 值类型*/public void setValue(String key, T value) {dataObjects.put(key, value);}/*** 获取上下文值* @param key 键名* @param 返回值类型* @return 对应的值,如果不存在则返回null*/public T getValue(String key) {return (T) dataObjects.get(key);}}
}
3.2 AbstractSupport 规则树抽象支持类
AbstractSupport 继承自多线程策略路由器,为具体业务实现提供基础支持。它使用 DefaultStrategyFactory.DynamicContext 作为策略执行的上下文,并提供缺省的多线程执行方法。
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/*** 抽象支持类* 继承自多线程策略路由器,为具体业务实现提供基础支持** 功能说明:* 1. 作为业务策略路由的抽象基类,提供多线程策略执行框架* 2. 使用DefaultStrategyFactory.DynamicContext作为策略执行的上下文* 3. 提供缺省的多线程执行方法,子类可根据需要重写** 泛型参数说明:* - String: 请求参数类型* - DefaultStrategyFactory.DynamicContext: 动态上下文类型,用于策略间数据传递* - String: 返回结果类型*/
public abstract class AbstractSupport extends AbstractMultiThreadStrategyRouter {/*** 多线程执行方法(缺省实现)* 子类可以重写此方法来实现具体的多线程业务逻辑** @param requestParameter 请求参数* @param dynamicContext 动态上下文,包含策略执行过程中的共享数据* @throws ExecutionException 执行过程中出现的异常* @throws InterruptedException 线程中断异常* @throws TimeoutException 执行超时异常*/@Overrideprotected void multiThread(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws ExecutionException, InterruptedException, TimeoutException {// 缺省的空实现,子类需要根据具体业务重写此方法// 默认不执行任何多线程操作,直接由单线程策略路由处理}
}
3.3 RootNode 根节点策略处理器
RootNode 是规则决策树的入口节点,负责整个策略链的启动和路由。它接收初始请求,并将请求路由到下一个合适的策略处理器。
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/*** 根节点策略处理器* 作为规则决策树的入口节点,负责整个策略链的启动和路由** 功能说明:* 1. 作为决策树的起始节点,接收初始请求* 2. 负责将请求路由到下一个合适的策略处理器(SwitchRoot)* 3. 记录根节点的执行日志,便于跟踪和调试** 设计特点:* - 继承AbstractSupport,具备多线程策略路由能力* - 使用@Component注解,作为Spring Bean管理* - 使用@Slf4j注解,提供日志记录能力*/
@Slf4j
@Component
public class RootNode extends AbstractSupport {// 下一级策略处理器(路由开关节点)@Autowiredprivate SwitchRoot switchRoot;/*** 业务处理方法* 实现具体的业务逻辑,这里是启动策略路由** @param requestParameter 请求参数(用户ID)* @param dynamicContext 动态上下文* @return 策略执行结果* @throws Exception 执行过程中可能抛出的异常*/@Overrideprotected String doApply(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 记录根节点执行日志log.info("【根节点】规则决策树 userId:{}", requestParameter);// 启动策略路由,将请求传递给下一个处理器return router(requestParameter, dynamicContext);}/*** 策略映射方法* 根据请求参数和上下文返回下一个策略处理器** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 下一个策略处理器(SwitchRoot)* @throws Exception 映射过程中可能抛出的异常*/@Overridepublic StrategyHandler get(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 直接返回SwitchRoot作为下一个处理器// 这里可以根据业务逻辑实现更复杂的路由选择return switchRoot;}
}
3.4 SwitchRoot 开关节点策略处理器
SwitchRoot 是规则决策树中的路由开关,负责将请求转发到具体的业务处理节点。它作为中间路由节点,记录执行日志并传递请求。
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/*** 开关节点策略处理器* 作为规则决策树中的路由开关,负责将请求转发到具体的业务处理节点** 功能说明:* 1. 作为决策树中的中间路由节点,接收来自根节点的请求* 2. 负责将请求路由到具体的业务处理节点(AccountNode)* 3. 记录开关节点的执行日志,便于跟踪请求流转** 设计特点:* - 继承AbstractSupport,具备多线程策略路由能力* - 使用@Component注解,作为Spring Bean管理* - 使用@Slf4j注解,提供日志记录能力* - 作为纯路由节点,不包含具体业务逻辑*/
@Slf4j
@Component
public class SwitchRoot extends AbstractSupport {// 具体的业务处理节点(账户节点)@Autowiredprivate AccountNode accountNode;/*** 业务处理方法* 实现路由转发逻辑,将请求传递给下一个处理器** @param requestParameter 请求参数(用户ID)* @param dynamicContext 动态上下文* @return 策略执行结果* @throws Exception 执行过程中可能抛出的异常*/@Overrideprotected String doApply(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 记录开关节点执行日志log.info("【开关节点】规则决策树 userId:{}", requestParameter);// 继续策略路由,将请求传递给下一个处理器return router(requestParameter, dynamicContext);}/*** 策略映射方法* 返回下一个策略处理器(AccountNode)** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 下一个策略处理器(AccountNode)* @throws Exception 映射过程中可能抛出的异常*/@Overridepublic StrategyHandler get(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 固定返回AccountNode作为下一个处理器// 这里可以实现基于条件判断的动态路由逻辑return accountNode;}
}
3.5 AccountNode 账户节点策略处理器
AccountNode 负责账户相关的业务逻辑处理,包括多线程异步数据加载和条件路由。它根据账户状态和用户级别进行动态路由决策。
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeoutException;
/*** 账户节点策略处理器* 负责账户相关的业务逻辑处理,包括多线程异步数据加载和条件路由** 功能说明:* 1. 多线程异步加载账户相关数据(账户状态、授信数据)* 2. 根据账户状态和用户级别进行动态路由决策* 3. 作为业务处理节点,包含具体的业务逻辑** 设计特点:* - 重写multiThread方法,实现多线程异步数据加载* - 根据业务条件动态选择下一个处理器* - 使用线程池执行异步任务,提高性能*/
@Slf4j
@Component
public class AccountNode extends AbstractSupport {// 会员级别1节点处理器@Autowiredprivate MemberLevelNode1 memberLevelNode1;// 会员级别2节点处理器@Autowiredprivate MemberLevelNode2 memberLevelNode2;// 线程池执行器,用于执行异步任务@Resourceprivate ThreadPoolExecutor threadPoolExecutor;/*** 多线程异步数据加载方法* 并行加载账户相关的多个数据源,提高执行效率** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @throws ExecutionException 执行异常* @throws InterruptedException 线程中断异常* @throws TimeoutException 超时异常*/@Overrideprotected void multiThread(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws ExecutionException, InterruptedException, TimeoutException {// 异步任务1:查询账户标签状态CompletableFuture accountType01 = CompletableFuture.supplyAsync(() -> {log.info("异步查询账户标签,账户标签;开户|冻结|止付|可用");return new Random().nextBoolean() ? "账户冻结" : "账户可用";}, threadPoolExecutor);// 异步任务2:查询授信数据状态CompletableFuture accountType02 = CompletableFuture.supplyAsync(() -> {log.info("异步查询授信数据,拦截|已授信|已降档");return new Random().nextBoolean() ? "拦截" : "已授信";}, threadPoolExecutor);// 等待所有异步任务完成,并将结果存入上下文CompletableFuture.allOf(accountType01, accountType02).thenRun(() -> {dynamicContext.setValue("accountType01", accountType01.join());dynamicContext.setValue("accountType02", accountType02.join());}).join();}/*** 业务处理方法* 执行账户相关的业务逻辑,并设置用户级别信息** @param requestParameter 请求参数(用户ID)* @param dynamicContext 动态上下文* @return 策略执行结果* @throws Exception 执行过程中可能抛出的异常*/@Overrideprotected String doApply(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {log.info("【账户节点】规则决策树 userId:{}", requestParameter);// 模拟查询用户级别(实际项目中应从数据库或服务获取)int level = new Random().nextInt(2);log.info("模拟查询用户级别 level:{}", level);// 将用户级别信息存入上下文,供后续节点使用dynamicContext.setLevel(level);// 继续策略路由return router(requestParameter, dynamicContext);}/*** 策略映射方法* 根据账户状态和用户级别动态选择下一个处理器** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 下一个策略处理器* @throws Exception 映射过程中可能抛出的异常*/@Overridepublic StrategyHandler get(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 从上下文中获取异步加载的数据String accountType01 = dynamicContext.getValue("accountType01");String accountType02 = dynamicContext.getValue("accountType02");int level = dynamicContext.getLevel();// 路由决策逻辑:// 1. 如果账户冻结,路由到会员级别1节点(可能是处理异常状态)if ("账户冻结".equals(accountType01)) {return memberLevelNode1;}// 2. 如果授信数据被拦截,路由到会员级别1节点if ("拦截".equals(accountType02)) {return memberLevelNode1;}// 3. 根据用户级别路由到不同的处理节点if (level == 1) {return memberLevelNode1;}// 4. 默认路由到会员级别2节点return memberLevelNode2;}
}
3.6 MemberLevelNode1 会员级别1节点策略处理器
MemberLevel1Node 负责处理级别1会员的具体业务逻辑,作为决策树的终端节点之一。它执行级别1会员的特定业务逻辑并返回结果。
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/*** 会员级别1节点策略处理器* 负责处理级别1会员的具体业务逻辑,作为决策树的终端节点之一** 功能说明:* 1. 执行级别1会员的特定业务逻辑* 2. 作为决策链的终端节点,返回最终处理结果* 3. 记录级别1节点的执行日志,便于跟踪和监控** 设计特点:* - 终端节点设计,不继续路由到其他节点* - 直接返回业务处理结果,结束决策流程* - 使用FastJSON序列化上下文信息,便于结果展示*/
@Slf4j
@Component
public class MemberLevelNode1 extends AbstractSupport {/*** 业务处理方法* 执行级别1会员的具体业务逻辑并返回结果** @param requestParameter 请求参数(用户ID)* @param dynamicContext 动态上下文,包含决策过程中的所有数据* @return 业务处理结果字符串,格式为"level1" + 上下文JSON* @throws Exception 执行过程中可能抛出的异常*/@Overrideprotected String doApply(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 记录级别1节点的执行日志log.info("【级别节点-1】规则决策树 userId:{}", requestParameter);// 返回处理结果:级别标识 + 上下文信息的JSON字符串return "level1" + JSON.toJSONString(dynamicContext);}/*** 策略映射方法* 作为终端节点,直接返回默认策略处理器,结束路由流程** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 默认策略处理器,实际不会继续执行* @throws Exception 映射过程中可能抛出的异常*/@Overridepublic StrategyHandler get(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 返回默认策略处理器,表示不再继续路由// 在实际执行中,router方法会检查到这是默认处理器并结束流程return defaultStrategyHandler;}
}
3.7 MemberLevelNode2 会员级别2节点策略处理器
MemberLevel2Node 负责处理级别2会员的具体业务逻辑,作为决策树的另一个终端节点。它执行级别2会员的特定业务逻辑并返回结果。
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/*** 会员级别2节点策略处理器* 负责处理级别2会员的具体业务逻辑,作为决策树的另一个终端节点** 功能说明:* 1. 执行级别2会员的特定业务逻辑* 2. 作为决策链的终端节点,返回最终处理结果* 3. 记录级别2节点的执行日志,便于跟踪和监控** 设计特点:* - 终端节点设计,不继续路由到其他节点* - 直接返回业务处理结果,结束决策流程* - 使用FastJSON序列化上下文信息,便于结果展示* - 与MemberLevelNode1结构对称,处理不同级别的会员*/
@Slf4j
@Component
public class MemberLevelNode2 extends AbstractSupport {/*** 业务处理方法* 执行级别2会员的具体业务逻辑并返回结果** @param requestParameter 请求参数(用户ID)* @param dynamicContext 动态上下文,包含决策过程中的所有数据* @return 业务处理结果字符串,格式为"level2" + 上下文JSON* @throws Exception 执行过程中可能抛出的异常*/@Overrideprotected String doApply(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 记录级别2节点的执行日志log.info("【级别节点-2】规则决策树 userId:{}", requestParameter);// 返回处理结果:级别标识 + 上下文信息的JSON字符串return "level2" + JSON.toJSONString(dynamicContext);}/*** 策略映射方法* 作为终端节点,直接返回默认策略处理器,结束路由流程** @param requestParameter 请求参数* @param dynamicContext 动态上下文* @return 默认策略处理器,实际不会继续执行* @throws Exception 映射过程中可能抛出的异常*/@Overridepublic StrategyHandler get(String requestParameter, DefaultStrategyFactory.DynamicContext dynamicContext) throws Exception {// 返回默认策略处理器,表示不再继续路由// 在实际执行中,router方法会检查到这是默认处理器并结束流程return defaultStrategyHandler;}
}
3.8 Test 规则树测试类
DesignTest 用于测试策略模式决策树的完整执行流程。它获取策略处理器,创建动态上下文,执行策略处理链,并输出最终结果。
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/*** 设计框架测试类* 用于测试策略模式决策树的完整执行流程** 功能说明:* 1. 测试整个规则决策树的执行流程* 2. 验证策略模式框架的正确性和性能* 3. 展示策略模式在实际业务中的应用效果** 测试流程:* 1. 获取策略处理器(根节点)* 2. 创建动态上下文* 3. 执行策略处理链* 4. 输出最终结果*/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest()
public class Test {// 注入策略工厂,用于获取策略处理器@Resourceprivate DefaultStrategyFactory defaultStrategyFactory;/*** 策略模式决策树测试方法* 测试完整的决策树执行流程** @throws Exception 执行过程中可能抛出的异常*/@Testpublic void test() throws Exception {// 1. 获取策略处理器(从根节点开始)StrategyHandler strategyHandler = defaultStrategyFactory.strategyHandler();// 2. 创建动态上下文对象,用于在策略节点间传递数据DefaultStrategyFactory.DynamicContext dynamicContext = new DefaultStrategyFactory.DynamicContext();// 3. 执行策略处理链,传入用户ID和上下文String result = strategyHandler.apply("yang", dynamicContext);// 4. 输出测试结果log.info("测试结果:{}", result);}
}
3.9 测试结果
测试结果显示,规则树模式能够成功执行复杂的业务逻辑,并通过多线程异步加载数据提高性能。测试结果包括各级节点的执行日志和最终处理结果。
INFO RootNode - 【根节点】规则决策树 userId:yang
INFO SwitchRoot - 【开关节点】规则决策树 userId:yang
INFO AccountNode - 异步查询账户标签,账户标签;开户|冻结|止付|可用
INFO AccountNode - 异步查询授信数据,拦截|已授信|已降档
INFO AccountNode - 【账户节点】规则决策树 userId:yang
INFO AccountNode - 模拟查询用户级别 level:1
INFO MemberLevelNode1 - 【级别节点-1】规则决策树 userId:yang
INFO DesignFrameworkTest - 测试结果:level1{"dataObjects":{"accountType02":"已授信","accountType01":"账户可用"},"level":1}
四、总结
规则树模式为处理复杂业务规则提供了优雅而强大的解决方案。通过将业务规则抽象为树形结构,我们实现了业务逻辑与核心代码的解耦,大大提高了系统的灵活性、可维护性和可扩展性。
核心优势
解耦与复用:业务规则与核心逻辑分离,规则可以复用和独立变化
灵活可配置:支持动态调整规则,无需修改代码和重新部署
可视化与可调试:规则树结构清晰,便于理解和调试复杂业务逻辑
性能优化:通过缓存、并行执行等技术提升规则执行效率
监控追踪:完整的执行追踪和监控能力,便于问题排查和性能分析
适用场景
业务规则复杂且频繁变更的系统、需要支持动态配置和热更新的业务场景、对可维护性和可扩展性要求较高的企业级应用、需要可视化展示和调试复杂业务规则的场景
实施建议
从简单的规则开始,逐步构建复杂的规则树、使用注解和反射机制实现规则节点的自动发现和管理、为规则节点添加缓存和监控能力,提升性能和可观测性、建立规则版本管理机制,支持规则的回滚和对比、提供规则可视化工具,降低业务人员的理解成本
规则树模式不仅是技术实现,更是一种架构思维。它帮助我们更好地处理复杂性,构建出更加灵活和健壮的软件系统。在数字化转型的今天,这种能力显得尤为重要。
如果有新的想法或问题,欢迎评论区留言讨论!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/966770.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!