Spring Boot 使用策略模式 + 注册表模式构建动态规则引擎
·
点击上方“程序员蜗牛g”,选择“设为星标”
跟蜗牛哥一起,每天进步一点点

程序员蜗牛g
大厂程序员一枚 跟蜗牛一起 每天进步一点点
32篇原创内容
公众号
if (user.getAge > 60 && user.getLevel() > 3) {// 规则A} else if (...) {// 规则B}// ...还有100多行"if地狱"
这种方式(指大量使用if-else的代码结构)扩展性差、难以测试,维护起来也头大。
此时登场:策略模式 + 注册表模式。
将这两种模式结合使用,你可以动态地插入规则,
并清晰流畅地执行它们——而无需每次都触及核心逻辑。
2.实战案例
2.1 说明

关系图如下:

2.2 定义Rule接口
public interface Rule<T extends Context, R> {/**规则名称*/String getName() ;/**评估规则*/R evaluate(T context) ;}
2.3 定义上下文对象

public interface Context {}

public class UserContext implements Context {private final User user ;public UserContext(User user) {this.user = user ;}public User getUser() {return user;}}
2.4 定义规则实现

用户年龄规则
@Componentpublic class UserAgeRule implements Rule<UserContext, Boolean> {@Overridepublic String getName() {return "user_age_rule";}@Overridepublic Boolean evaluate(UserContext context) {if (context == null) {throw new IllegalArgumentException("Context must not be null");}return context.getAge() > 18 ;}}
用户等级规则
@Componentpublic class UserLevelRule implements Rule<UserContext, Boolean> {@Overridepublic String getName() {return "user_level_rule";}@Overridepublic Boolean evaluate(UserContext context) {if (context == null) {throw new IllegalArgumentException("Context must not be null");}return context.getUser().getLevel() >= 3 ;}}
辅助类
public class User {private String name ;private Integer age ;private Integer level ;// getters, setters, constructs}
2.5 定义注册表Registry

@Componentpublic class RuleRegistry {private final Map<String, Rule<?, ?>> ruleStore = new HashMap<>();public RuleRegistry(List<Rule<?, ?>> rules) {rules.forEach(rule -> ruleStore.put(rule.getName(), rule));}public <T extends Context, R> R execute(String ruleName, T context) {Rule<T, R> rule = getRuleInternal(ruleName);return rule.evaluate(context);}@SuppressWarnings("unchecked")private <T extends Context, R> Rule<T, R> getRuleInternal(String ruleName) {Rule<?, ?> rule = ruleStore.get(ruleName);if (rule == null) {throw new IllegalArgumentException("Rule not found: " + ruleName);}return (Rule<T, R>) rule;}}
2.6 规则调度引擎

@Servicepublic class RuleEngine {private final RuleRegistry ruleRegistry;public RuleEngine(RuleRegistry ruleRegistry) {this.ruleRegistry = ruleRegistry;}public <T extends Context, R> R execute(String ruleName, T context) {try {return ruleRegistry.execute(ruleName, context) ;} catch (IllegalArgumentException e) {throw new RuntimeException("Rule '" + ruleName + "' not found or invalid context", e);}}}
2.7 测试
最后,我们通过一个Controller接口进行测试。
@RestController@RequestMapping("/rules")public class RuleController {private final RuleEngine ruleEngine;public RuleController(RuleEngine ruleEngine) {this.ruleEngine = ruleEngine;}@PostMapping("/evaluate")public ResponseEntity<Boolean> evaluate(@RequestParam String rule, @RequestBody User user) {UserContext context = new UserContext(user) ;return ResponseEntity.ok(ruleEngine.execute(rule, context));}}
测试上面的2个简单规则


如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!
更多推荐

所有评论(0)