发放红包是高频开发需求,将每个条件校验抽象成 handler 模型,对部分参数进行配置化,使得后面的红包需求开发量越来越少,极大提高代码复用率。使用java实现出来。
你这个想法很棒,是一个典型的规则引擎式设计 ,通过将每个发放红包的业务规则抽象成 Handler(处理器) ,实现一个可配置的、可扩展的链式校验系统。下面是一个用 Java 实现的完整思路和代码框架:
💡 设计思路
✅ 核心思想:
• 每一个"发红包"的校验条件,抽象为一个 RuleHandler。
• 使用"责任链模式"串联多个 Handler。
• 支持配置式启用某些 Handler(通过配置文件、数据库、策略中心等)。
🧱 类图结构(简化)
lua
+------------------+
| RuleHandler | <-- 接口(抽象规则处理器)
+------------------+
▲
+------------+-------------+
| |
+-------------------+ +--------------------+
| LoginDaysHandler | | UserLevelHandler | ...(具体实现类)
+-------------------+ +--------------------+
+----------------------+
| RuleHandlerChain | <-- 构建责任链 & 执行
+----------------------+
+----------------------+
| RedPacketService | <-- 对外发放红包接口
+----------------------+
🧩 1. 抽象 Handler 接口
arduino
public interface RuleHandler {
boolean handle(RedPacketContext context);
String getName();
}
🧩 2. 示例 Handler:登录天数校验
typescript
public class LoginDaysHandler implements RuleHandler {
@Override
public boolean handle(RedPacketContext context) {
return context.getUser().getLoginDays() >= 7;
}
@Override
public String getName() {
return "LoginDaysHandler";
}
}
🧩 3. 示例 Handler:用户等级校验
typescript
public class UserLevelHandler implements RuleHandler {
@Override
public boolean handle(RedPacketContext context) {
return context.getUser().getLevel() >= 3;
}
@Override
public String getName() {
return "UserLevelHandler";
}
}
🧩 4. RuleHandlerChain:可配置执行链
arduino
public class RuleHandlerChain {
private final List<RuleHandler> handlers = new ArrayList<>();
public RuleHandlerChain(List<RuleHandler> allHandlers, List<String> enabledHandlerNames) {
for (RuleHandler handler : allHandlers) {
if (enabledHandlerNames.contains(handler.getName())) {
handlers.add(handler);
}
}
}
public boolean execute(RedPacketContext context) {
for (RuleHandler handler : handlers) {
if (!handler.handle(context)) {
return false; // 某一环节失败,阻断发红包
}
}
return true;
}
}
🧩 5. 上下文类 RedPacketContext
typescript
public class RedPacketContext {
private final User user;
private final Map<String, Object> params = new HashMap<>();
public RedPacketContext(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public Object getParam(String key) {
return params.get(key);
}
public void setParam(String key, Object value) {
params.put(key, value);
}
}
🧩 6. 用户类(简化)
arduino
public class User {
private int loginDays;
private int level;
// constructor + getters/setters
}
🧩 7. 红包发放服务
kotlin
public class RedPacketService {
private final RuleHandlerChain ruleHandlerChain;
public RedPacketService(RuleHandlerChain ruleHandlerChain) {
this.ruleHandlerChain = ruleHandlerChain;
}
public boolean tryGrantRedPacket(RedPacketContext context) {
if (ruleHandlerChain.execute(context)) {
// 发放红包逻辑
System.out.println("✅ 红包发放成功");
return true;
} else {
System.out.println("❌ 红包发放失败,未通过规则校验");
return false;
}
}
}
🔧 8. 配置方式(可来自配置中心、数据库、JSON)
ini
public class App {
public static void main(String[] args) {
User user = new User();
user.setLoginDays(10);
user.setLevel(4);
RedPacketContext context = new RedPacketContext(user);
List<RuleHandler> allHandlers = List.of(
new LoginDaysHandler(),
new UserLevelHandler()
);
// 可配置的启用项
List<String> enabledRules = List.of(
"LoginDaysHandler",
"UserLevelHandler"
);
RuleHandlerChain chain = new RuleHandlerChain(allHandlers, enabledRules);
RedPacketService service = new RedPacketService(chain);
service.tryGrantRedPacket(context);
}
}
✅ 优势总结
☑️ 高复用 | 每个 handler 独立复用,不同活动组合即可 |
---|---|
☑️ 易配置 | 支持配置开关控制规则链 |
☑️ 易扩展 | 新增规则只需添加新 handler |
☑️ 易测试 | 每个 handler 可单测,调试方便 |
太好了,那我们现在来把这个「规则引擎」模块做得更像一个真正可配置、可插拔的 Spring Boot 模块,让你后续几乎零改动就能支持新的活动规则。
🚀 扩展目标
✅ 使用 Spring Boot 支持:
-
使用注解标记 RuleHandler
-
自动收集所有 RuleHandler Bean
-
通过配置文件控制启用哪些 handler
-
Spring Boot Starter 风格:可独立打包复用
🧩 第一步:创建注解 @Rule
用于标记每一个 Handler 的唯一名称。
less
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component // 让 Spring 自动扫描
public @interface Rule {
String value(); // handler 的唯一标识
}
🧩 第二步:修改接口 RuleHandler
java
public interface RuleHandler {
boolean handle(RedPacketContext context);
}
❗ 不再需要 getName 方法,使用 @Rule("xxx") 代替。
🧩 第三步:示例 handler 使用注解
typescript
@Rule("LoginDaysHandler")
public class LoginDaysHandler implements RuleHandler {
@Override
public boolean handle(RedPacketContext context) {
return context.getUser().getLoginDays() >= 7;
}
}
🧩 第四步:Handler 自动收集器 RuleHandlerFactory
收集所有 handler,并根据配置启用
kotlin
@Component
public class RuleHandlerFactory {
private final Map<String, RuleHandler> ruleHandlerMap = new HashMap<>();
@Autowired
public RuleHandlerFactory(List<RuleHandler> handlers) {
for (RuleHandler handler : handlers) {
Rule annotation = handler.getClass().getAnnotation(Rule.class);
if (annotation != null) {
ruleHandlerMap.put(annotation.value(), handler);
}
}
}
public List<RuleHandler> getHandlers(List<String> enabledRuleNames) {
return enabledRuleNames.stream()
.map(ruleHandlerMap::get)
.filter(Objects::nonNull)
.toList();
}
}
🧩 第五步:配置文件控制规则启用
markdown
red-packet:
enabled-rules:
- LoginDaysHandler
- UserLevelHandler
对应配置类:
typescript
@Configuration
@ConfigurationProperties(prefix = "red-packet")
public class RedPacketProperties {
private List<String> enabledRules = new ArrayList<>();
public List<String> getEnabledRules() {
return enabledRules;
}
public void setEnabledRules(List<String> enabledRules) {
this.enabledRules = enabledRules;
}
}
🧩 第六步:注入规则链与服务
kotlin
@Service
public class RedPacketService {
private final RuleHandlerChain ruleHandlerChain;
@Autowired
public RedPacketService(RuleHandlerFactory factory, RedPacketProperties properties) {
List<RuleHandler> handlers = factory.getHandlers(properties.getEnabledRules());
this.ruleHandlerChain = new RuleHandlerChain(handlers);
}
public boolean tryGrantRedPacket(RedPacketContext context) {
if (ruleHandlerChain.execute(context)) {
System.out.println("✅ 红包发放成功");
return true;
} else {
System.out.println("❌ 红包发放失败,未通过规则校验");
return false;
}
}
}
✅ 最终效果
你只需要:
-
新增一个类,标注 @Rule("XXX")
-
在 application.yml 中加一句:
yaml
red-packet:
enabled-rules:
- XXX
系统就能自动启用这个规则!无需改代码!
🛠️ 想做成独立模块(Starter)?
你可以将:
• @Rule 注解
• RuleHandler, RuleHandlerChain
• RedPacketProperties, RuleHandlerFactory
• 抽象服务接口
封装到一个模块 rule-engine-spring-boot-starter 中,作为一个通用"规则引擎",可用于红包、优惠券、会员推荐等场景。