从组合爆炸到优雅分派:复杂策略系统的工程化实现
干货分享,感谢您的阅读!在实际的工程系统中,我们经常遇到这样的场景:
- 推荐系统需要根据用户类型、内容标签、来源渠道、活动配置等组合选择不同策略;
 - 风控系统需要根据地区、设备、交易类型、时间段来执行不同规则;
 - 广告投放平台需要根据预算层级、素材类型、投放环境等参数自动选择出价逻辑。
 
这类问题的共同特点是:
-  
维度多(组合爆炸)
 -  
策略多(共用与特例并存)
 -  
易变(新场景不断增加)
 
于是,大厂开始频繁地在面试中抛出类似的“策略组合分派系统设计题”,考察候选人的系统抽象能力、代码组织能力与工程可扩展性思维。
| 公司 | 常见题型方向 | 设计考察点 | 
|---|---|---|
| 字节跳动(抖音、头条) | 推荐/广告策略系统;特征组合策略匹配 | 注解注册、组合分派、优先级策略 | 
| 阿里巴巴(淘系、蚂蚁) | 营销/风控/规则引擎设计 | 规则抽象、DSL匹配、策略落地与容器化 | 
| 腾讯(广告、视频号) | 用户画像 + 多维策略投放系统 | 策略复用与动态优先级 | 
| 美团 | 配送调度策略 / 智能推荐规则 | 动态分派、参数维度建模 | 
| 京东 | 价格策略 / 优惠券适配 / 库存调度 | 组合枚举 + 注解注册 + 策略路由 | 
| 滴滴 / 高德 | 路线规划 / 费用策略 | 多维输入组合 + 最优策略选择 | 
| Shopee / Lazada | 营销活动策略选择 | 国际化组合、规则解耦 | 
当策略逻辑开始“乘法爆炸”,我们该如何在不崩溃的前提下,让系统依旧优雅?我在之前很早的博客中有讲解过简单的一些策略解法:
- 深入解析工厂模式与策略模式的结合:从外卖平台折扣谈起
 - 注解驱动的策略模式实现:简化复杂业务逻辑
 
但是这种典型的 「策略组合 + 注解注册 + 策略分派」思维,基于粉丝求助,我想今天直接拿出来做一次博客分享:当策略逻辑开始“乘法爆炸”,我们该如何在不崩溃的前提下,让系统依旧优雅?
一、题目背景:复杂组合策略系统设计
在大型业务系统中,策略逻辑往往随着场景扩展而成倍增长。
 例如,在推荐、活动、风控、广告、内容审核等系统中,不同的 用户类型(A)、渠道来源(B)、运行环境(C)、触发场景(D)共同决定了最终的策略选择。
如果我们使用多层 if-else 或硬编码去处理这些分支,不仅难以维护,还极易引发逻辑冲突与策略回退问题。
为此,我们希望设计一个:
基于多维组合 + 注解注册 + 动态分派 的策略系统。
二、系统要求与考察点
(一)基础要求
| 模块 | 说明 | 
|---|---|
| A | 一级维度(2 种) | 
| B | 二级维度(3 种) | 
| C | 环境配置(2 种) | 
| D | 场景触发(4 种) | 
组合总数:2×3×2×4=48,我们需要支持:
-  
为特定组合分配专属策略;
 -  
多组合共用一个策略;
 -  
默认兜底策略;
 -  
支持模糊匹配(如仅匹配 C、D);
 -  
自动注册、自动分派;
 -  
可扩展到 Spring 环境。
 
(二)设计考察点
| 维度 | 说明 | 
|---|---|
| 架构抽象能力 | 策略接口 → 注册器 → 分派器,职责清晰 | 
| 可扩展性 | 新增枚举或策略无需修改核心逻辑 | 
| 冲突检测 | 当多个策略匹配时,选“最具体”策略 | 
| 工程化能力 | 支持 Spring 扫描、Bean 装配、单元测试 | 
| 通用性 | 可提炼成独立策略服务用于其他项目 | 
三、核心架构设计
整个系统的设计可以类比为一个“策略中枢大脑”,当外部输入一组业务信息(A、B、C、D)时,它能自动找到最合适的策略实现并执行。
这套架构共分为 六个核心层次,每一层都承担着清晰的职责,层层解耦、自然协作👇
| 层级 | 职责 | 
|---|---|
| 1️⃣ 枚举定义 | 定义 A/B/C/D 的取值 | 
| 2️⃣ 组合类型 | 定义 Combination | 
| 3️⃣ 策略接口 | 统一执行规范 | 
| 4️⃣ 策略注解 | 通过 @StrategyFor 注册规则 | 
| 5️⃣ 策略注册器 | 自动扫描并注册策略 | 
| 6️⃣ 策略分派器 | 匹配最优策略并执行 | 
我们可实现从“输入组合 → 自动选择策略 → 执行结果”的完整链路:

这一套架构的核心理念是:
用注解替代硬编码匹配,用分派器替代 if-else 嵌套。
通过“注册-匹配-执行”三步走,实现了一个可扩展、可热插拔的策略系统,新增策略时只需写一个新类 + 加一个注解,系统即可自动识别。
四、具体技术实现
(一)枚举与组合类设计
1. 具体枚举定义与实现
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums;/*** @program: zyfboot-javabasic* @description: 条件类型A* @author: zhangyanfeng* @create: 2025-11-02 15:23**/
public enum AType {A1, A2
}
 
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums;/*** @program: zyfboot-javabasic* @description: 条件类型B* @author: zhangyanfeng* @create: 2025-11-02 15:24**/
public enum BType {B1, B2, B3
} 
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums;/*** @program: zyfboot-javabasic* @description: 条件类型C* @author: zhangyanfeng* @create: 2025-11-02 15:24**/
public enum CType {C1, C2
}
 
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums;/*** @program: zyfboot-javabasic* @description: 条件类型D* @author: zhangyanfeng* @create: 2025-11-02 15:24**/
public enum DType {D1, D2, D3, D4
}
 
2. 基本组合类定义
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.types;import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.AType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.BType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.CType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.DType;/*** @program: zyfboot-javabasic* @description: 枚举组合类* @author: zhangyanfeng* @create: 2025-11-02 15:29**/
public class Combination {private AType a;private BType b;private CType c;private DType d;public Combination(AType a, BType b, CType c, DType d) {this.a = a;this.b = b;this.c = c;this.d = d;}public AType getA() {return a;}public BType getB() {return b;}public CType getC() {return c;}public DType getD() {return d;}@Overridepublic String toString() {return String.format("%s|%s|%s|%s", a, b, c, d);}
}
 
(二)注解与策略接口
1. 基本注解设计
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.annotation;import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.AType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.BType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.CType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.DType;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** @program: zyfboot-javabasic* @description: 注解策略接口* @author: zhangyanfeng* @create: 2025-11-02 18:23**/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface StrategyFor {AType[] a() default {};BType[] b() default {};CType[] c() default {};DType[] d() default {};
}
 
2.基本策略接口设计
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy;import org.zyf.javabasic.designpatterns.strategy.tiktok.base.types.Combination;/*** @program: zyfboot-javabasic* @description: 策略接口* @author: zhangyanfeng* @create: 2025-11-02 18:25**/
public interface Strategy {void execute(Combination combination);
}
 
(三)示例策略实现
我们通过多个策略实现类来展示策略系统的声明与复用。每个策略类都通过 @StrategyFor 注解标明其适配的组合条件:
-  
StrategyAlpha:覆盖A1+{B1,B2}+C1下的所有D情况; -  
StrategyC2D4:专门处理C2且D4的组合,无视 A/B; -  
DefaultStrategy:不限制任何条件,作为兜底策略。 
设计目标实现“最小化重复”与“高可读性”的策略复用。
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.impl;import org.springframework.stereotype.Component;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.AType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.BType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.CType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.Strategy;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.annotation.StrategyFor;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.types.Combination;/*** @program: zyfboot-javabasic* @description: 覆盖 A1 + {B1,B2} + C1 下的所有 D 情况;* @author: zhangyanfeng* @create: 2025-11-02 18:28**/
@StrategyFor(a = {AType.A1}, b = {BType.B1, BType.B2}, c = {CType.C1})
@Component
public class StrategyAlpha implements Strategy {@Overridepublic void execute(Combination combination) {System.out.println("StrategyAlpha handling: " + combination);}
}
 
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.impl;import org.springframework.stereotype.Component;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.CType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.DType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.Strategy;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.annotation.StrategyFor;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.types.Combination;/*** @program: zyfboot-javabasic* @description: StrategyC2D4:专门处理 C2 且 D4 的组合,无视 A/B;* @author: zhangyanfeng* @create: 2025-11-02 18:32**/
@StrategyFor(c = {CType.C2}, d = {DType.D4})
@Component
public class StrategyC2D4 implements Strategy {@Overridepublic void execute(Combination combination) {System.out.println("StrategyC2D4 handling: " + combination);}
}
 
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.impl;import org.springframework.stereotype.Component;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.Strategy;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.annotation.StrategyFor;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.types.Combination;/*** @program: zyfboot-javabasic* @description: 不限制任何条件,作为兜底策略。* @author: zhangyanfeng* @create: 2025-11-02 18:32**/
@StrategyFor
@Component
public class DefaultStrategy implements Strategy {@Overridepublic void execute(Combination combination) {System.out.println("DefaultStrategy handling: " + combination);}
}
 
说明:
- 可通过多个值覆盖多种组合;
 -  
未指定字段表示通配所有值;
 -  
默认策略作为兜底。
 
(四)策略注册器
StrategyRegistry 是连接“策略实现”和“策略分派”的桥梁,它让策略系统具备 自动化、可扩展、可维护 的工程化特性。具体代码如下:
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.core.registry;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.Strategy;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.annotation.StrategyFor;import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** @program: zyfboot-javabasic* @description: 策略注册器(核心组件)** 【职责说明】* 该组件在系统启动阶段自动扫描 Spring 容器中所有实现了 Strategy 接口的 Bean,* 读取它们的 @StrategyFor 注解配置,并将“策略实例 + 匹配规则”注册到策略列表中。* 后续由策略分派器(StrategyDispatcher)进行策略匹配与执行。** 【设计目标】* - 自动注册:免手工配置* - 解耦扩展:策略定义与业务分离* - 统一管理:集中维护策略元信息** @author:* @create: 2025-11-02 18:37**/
@Component
public class StrategyRegistry implements ApplicationContextAware {/** Spring 上下文,用于获取所有 Strategy Bean */private ApplicationContext applicationContext;/** 策略注册表,存放系统内所有策略信息 */private final List<RegisteredStrategy> strategies = new ArrayList<>();/*** 内部静态类,用于封装单个策略的注册信息:* 包含策略对应的注解(匹配规则)与策略实例(执行对象)*/public static class RegisteredStrategy {private final StrategyFor annotation;private final Strategy instance;public RegisteredStrategy(StrategyFor annotation, Strategy instance) {this.annotation = annotation;this.instance = instance;}public StrategyFor getAnnotation() {return annotation;}public Strategy getInstance() {return instance;}}/*** 容器启动后自动执行** 1. 从 Spring 容器中获取所有实现 Strategy 接口的 Bean;* 2. 判断是否标注了 @StrategyFor;* 3. 如果是,则解析注解并注册到策略列表;* 4. 最终打印所有已注册的策略信息。*/@PostConstructpublic void init() {// 获取容器中所有 Strategy 类型的 BeanMap<String, Strategy> beans = applicationContext.getBeansOfType(Strategy.class);// 遍历所有策略 Bean,解析注解并注册beans.values().forEach(strategy -> {Class<?> clazz = strategy.getClass();if (clazz.isAnnotationPresent(StrategyFor.class)) {StrategyFor annotation = clazz.getAnnotation(StrategyFor.class);strategies.add(new RegisteredStrategy(annotation, strategy));System.out.println("[StrategyRegistry] 注册策略: " + clazz.getSimpleName());}});// 打印统计结果System.out.println("[StrategyRegistry] 共注册策略数量: " + strategies.size());}/*** 对外暴露所有注册策略* 供分派器(StrategyDispatcher)使用*/public List<RegisteredStrategy> getStrategies() {return strategies;}/*** 由 Spring 注入 ApplicationContext*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}
}
 
StrategyRegistry 是策略组合系统的“信息中心”,它在整个架构中承担了 “策略收集器 + 注册中心” 的角色:
| 功能 | 说明 | 
|---|---|
| 自动发现 | 系统启动后,自动扫描所有实现 Strategy 接口的策略类 | 
| 注解解析 | 从每个策略类的 @StrategyFor 注解中提取匹配条件 | 
| 集中注册 | 将策略实例与注解信息封装为 RegisteredStrategy 对象并缓存 | 
| 提供查询 | 为分派器提供统一的策略清单,便于执行阶段快速定位策略 | 
设计优势:
-  
无需硬编码注册;
 -  
符合“开闭原则”(新增策略仅需新建类 + 注解);
 -  
可视化输出策略注册日志,方便排查;
 -  
轻量高效,适配生产级 Spring 应用。
 
(五)策略分派器
StrategyDispatcher 是策略系统的「调度核心」,它让策略体系从“静态 if-else 判断”进化为动态、可配置、可演化的智能分派系统。具体实现如下:
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.core.dispatcher;import org.springframework.stereotype.Component;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.core.registry.StrategyRegistry;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.Strategy;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.annotation.StrategyFor;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.types.Combination;import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;/*** @program: zyfboot-javabasic* @description: 策略分派器(Strategy Dispatcher)** 【职责说明】* 该组件是整个策略系统的“大脑”,负责根据输入的组合(A/B/C/D)信息,* 从注册中心中查找最匹配的策略实例,并将其分派执行。** 【核心流程】* 1️⃣ 从注册中心获取所有已注册策略;* 2️⃣ 根据 @StrategyFor 注解规则过滤出匹配的策略;* 3️⃣ 若存在多个匹配,按“具体度”(specificity)降序排序;* 4️⃣ 返回最具体的策略;若无匹配,则回退到默认策略。** 【特点】* - 注解驱动、动态匹配* - 自动优先选择“最具体”策略(即匹配条件最多者)* - 可检测策略冲突(防止多个策略规则重复)* - 支持默认策略兜底** @author:* @create: 2025-11-02 18:39**/
@Component
public class StrategyDispatcher {/** 策略注册中心,由 Spring 注入 */private final StrategyRegistry registry;public StrategyDispatcher(StrategyRegistry registry) {this.registry = registry;}/*** 分派策略:根据组合(Combination)匹配最合适的策略实现*/public Strategy dispatch(Combination combination) {// 1️⃣ 获取所有匹配当前组合的策略List<StrategyRegistry.RegisteredStrategy> matched = registry.getStrategies().stream().filter(rs -> matches(rs.getAnnotation(), combination)).collect(Collectors.toList());System.out.println("[StrategyDispatcher] 组合 " + combination + " 匹配策略数量: " + matched.size());// 2️⃣ 无匹配策略则尝试默认策略if (matched.isEmpty()) {return findDefaultStrategy().orElseThrow(() -> new RuntimeException("No matching strategy and no default strategy found for: " + combination));}// 打印匹配详情matched.forEach(s -> System.out.println(" -> 匹配到: " + s.getInstance().getClass().getSimpleName()+ " specificity=" + specificity(s.getAnnotation())));// 3️⃣ 检查是否存在多个“等价”策略(即规则冲突)if (matched.size() > 1) {matched.sort(Comparator.comparingInt((StrategyRegistry.RegisteredStrategy rs) -> specificity(rs.getAnnotation())).reversed());int top = specificity(matched.get(0).getAnnotation());int next = specificity(matched.get(1).getAnnotation());if (top == next) {throw new IllegalStateException("存在策略冲突!匹配到多个等价策略: "+ matched.stream().map(s -> s.getInstance().getClass().getSimpleName()).collect(Collectors.joining(", ")));}}// 4️⃣ 返回“最具体”的策略(规则约束最多者优先)return matched.get(0).getInstance();}/*** 判断注解定义的规则是否与当前组合匹配* - 若注解未指定该维度(数组为空),视为“通配”* - 若注解指定了,则必须完全匹配*/private boolean matches(StrategyFor anno, Combination c) {if (anno == null || c == null) return false;if (anno.a().length > 0 && Arrays.stream(anno.a()).noneMatch(x -> x == c.getA())) return false;if (anno.b().length > 0 && Arrays.stream(anno.b()).noneMatch(x -> x == c.getB())) return false;if (anno.c().length > 0 && Arrays.stream(anno.c()).noneMatch(x -> x == c.getC())) return false;if (anno.d().length > 0 && Arrays.stream(anno.d()).noneMatch(x -> x == c.getD())) return false;return true;}/*** 计算策略“具体度”:* 指定枚举值越多,代表策略越具体(优先级越高)*/private int specificity(StrategyFor anno) {if (anno == null) return 0;return (anno.a() == null ? 0 : anno.a().length)+ (anno.b() == null ? 0 : anno.b().length)+ (anno.c() == null ? 0 : anno.c().length)+ (anno.d() == null ? 0 : anno.d().length);}/*** 从注册中心中查找默认策略(DefaultStrategy)* 实际项目中可改为通过注解或配置文件标识默认策略*/private Optional<Strategy> findDefaultStrategy() {return registry.getStrategies().stream().map(StrategyRegistry.RegisteredStrategy::getInstance).filter(s -> s.getClass().getSimpleName().equals("DefaultStrategy")).findFirst();}
}
 
StrategyDispatcher 是整个「策略组合系统」的核心控制器。它的职责就像调度中心,接收业务输入(A/B/C/D 组合),然后根据注册器提供的策略信息,智能地挑选出最合适的策略并执行。
| 功能点 | 说明 | 
|---|---|
| 动态匹配 | 依据注解匹配当前组合条件 | 
| 具体优先 | 指定条件越多的策略,优先级越高 | 
| 冲突检测 | 多个策略规则重复时抛出异常 | 
| 默认兜底 | 无匹配策略时自动启用 DefaultStrategy | 
| 日志可观测 | 打印匹配过程、策略选择与具体度,便于调试 | 
设计亮点:
-  
实现了策略体系的“智能分派”;
 -  
支持多维度组合匹配;
 -  
保持策略扩展与分派逻辑解耦;
 -  
可通过注解灵活控制策略适配范围。
 
(六)启动测试与校验
通过 StrategyDispatcherSpringTest 集成测试方式验证策略分派器 StrategyDispatcher 的实际行为。模拟不同的业务组合(Combination),确保分派逻辑能够正确命中对应策略或回退默认策略。
package org.zyf.javabasic.designpatterns.strategy.tiktok.base.biz;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.core.dispatcher.StrategyDispatcher;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.AType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.BType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.CType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.enums.DType;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.Strategy;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.impl.DefaultStrategy;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.impl.StrategyAlpha;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.strategy.impl.StrategyC2D4;
import org.zyf.javabasic.designpatterns.strategy.tiktok.base.types.Combination;import java.util.ArrayList;
import java.util.List;import static org.junit.Assert.assertTrue;/*** @program: zyfboot-javabasic* @description: 业务测试(SpringBootTest)* @author: zhangyanfeng* @create: 2025-11-02 19:54**/
@RunWith(SpringRunner.class)
@SpringBootTest
public class StrategyDispatcherSpringTest {@Autowiredprivate StrategyDispatcher dispatcher;@Testpublic void testAlphaMatch() {Combination combo = new Combination(AType.A1, BType.B2, CType.C1, DType.D3);Strategy strategy = dispatcher.dispatch(combo);strategy.execute(combo);assertTrue(strategy instanceof StrategyAlpha);}@Testpublic void testC2D4Match() {Combination combo = new Combination(AType.A2, BType.B3, CType.C2, DType.D4);Strategy strategy = dispatcher.dispatch(combo);strategy.execute(combo);assertTrue(strategy instanceof StrategyC2D4);}@Testpublic void testDefaultMatch() {Combination combo = new Combination(AType.A2, BType.B3, CType.C1, DType.D2);Strategy strategy = dispatcher.dispatch(combo);strategy.execute(combo);assertTrue(strategy instanceof DefaultStrategy);}@Testpublic void testAll48Combinations() {List<String> results = new ArrayList<>();// 遍历所有组合for (AType a : AType.values()) {for (BType b : BType.values()) {for (CType c : CType.values()) {for (DType d : DType.values()) {// 构造组合对象Combination combo = new org.zyf.javabasic.designpatterns.strategy.tiktok.base.types.Combination(a, b, c, d);// 分派策略Strategy strategy = dispatcher.dispatch(combo);// 记录结果String strategyName = strategy == null ? "null" : strategy.getClass().getSimpleName();results.add(String.format("%s => %s", combo, strategyName));}}}}// 输出结果results.forEach(System.out::println);// 简单验证默认策略是否存在boolean defaultUsed = results.stream().anyMatch(r -> r.endsWith(DefaultStrategy.class.getSimpleName()));assert defaultUsed : "至少有组合命中默认策略";}
} 
1. 测试目标与说明
| 测试方法 | 输入组合 | 期望命中策略 | 说明 | 
|---|---|---|---|
testAlphaMatch() | (A1, B2, C1, D3) | StrategyAlpha | 验证多维度精确匹配策略分派是否正确 | 
testC2D4Match() | (A2, B3, C2, D4) | StrategyC2D4 | 检查特定 C/D 组合策略的命中逻辑 | 
testDefaultMatch() | (A2, B3, C1, D2) | DefaultStrategy | 测试无匹配场景下的默认策略回退机制 | 
2. 验证说明
为了方便我们直接选取testAlphaMatch()说明如下:

五、总结:策略组合系统的魅力
面对用户类型、渠道、场景、环境这些多维组合,如果仍然依赖 if-else,代码很容易变成一团乱麻,逻辑一多就炸掉。而使用“组合 + 注解 + 分派器”的方式,我们把复杂逻辑抽象出来,系统可以自动根据输入选择最合适的策略,从而让复杂问题变得清晰可控。
新增策略也变得非常简单,只需写一个策略类,加上注解就能被系统识别,无需修改核心逻辑,也不用担心破坏已有功能。当多个策略匹配时,分派器会根据“具体度”自动判断优先级,同时检测策略冲突,避免重复或覆盖问题。而即便某个组合没有策略覆盖,默认策略也会顶上,保证系统不会出错。
更棒的是,这套系统经过了全面测试,可以遍历所有 48 种组合,确保每种情况都有对应策略,并且在匹配过程中打印日志,方便问题定位和调试。整个架构不仅适用于推荐、广告、风控等业务场景,还具有高度的复用性和可扩展性——即便未来新增维度或枚举值,核心逻辑几乎无需改动,系统自然就能支持。
用一句话总结就是:通过“组合 + 注解 + 分派器”,我们把复杂业务逻辑变得可维护、可扩展,而且更稳健,再也不用被策略乘法爆炸吓到。
