如何为包含多字段的类设计可维护的复杂条件判断实现方案?
订单变更多条件判断场景的优化设计方案
首选方案:规则对象注册表模式
该模式完全规避了多维度无层级的条件嵌套问题,完全符合开闭原则,可维护性极强,实现逻辑如下:
- 定义统一规则接口
所有业务规则都实现该通用接口,示例伪代码如下:
public interface OrderChangeRule { // 判断当前订单变更是否命中该规则 boolean matches(OrderChange orderChange); // 命中规则后执行的业务逻辑 void execute(OrderChange orderChange); }
- 独立实现每个业务规则
每个业务规则对应一个单独的实现类,条件判断和业务逻辑内聚在同一个类中,互不干扰。例如「RETAIL类型、FURNITURE品类、订单状态变更为PAID时发通知」的规则实现如下:
public class RetailFurniturePaidNotifyRule implements OrderChangeRule { @Override public boolean matches(OrderChange orderChange) { Order newOrder = orderChange.getNewOrder(); // 固定不变的字段直接读new_order if (newOrder.getOrderType() != OrderType.ORDER_TYPE_RETAIL) { return false; } if (newOrder.getOrderCategory() != OrderCategory.ORDER_CATEGORY_FURNITURE) { return false; } // 可变字段对比新旧值判断变更 return orderChange.getOldOrder().getOrderStatus() != OrderStatus.ORDER_STATUS_PAID && newOrder.getOrderStatus() == OrderStatus.ORDER_STATUS_PAID; } @Override public void execute(OrderChange orderChange) { // 执行发送特定通知邮件的逻辑 } }
- 实现规则注册表
项目启动时将所有规则实现类注册到统一的注册表中,也可以通过依赖注入框架自动扫描收集所有OrderChangeRule的实现类存入列表。 - 执行逻辑
收到OrderChange对象时,遍历注册表中的所有规则,只要规则的matches方法返回true,就执行对应execute方法即可。如果业务要求同一变更最多触发一个规则,可给规则新增优先级字段,命中最高优先级的规则后终止遍历即可。
优化补充:通用判断逻辑复用
可以将高频使用的判断条件抽成通用谓词工具类,避免每个规则里重复编写判断代码:
public class OrderChangePredicates { // 判断是否为零售订单 public static boolean isRetailOrder(OrderChange c) { return c.getNewOrder().getOrderType() == OrderType.ORDER_TYPE_RETAIL; } // 判断订单品类是否为家具 public static boolean isFurnitureCategory(OrderChange c) { return c.getNewOrder().getOrderCategory() == OrderCategory.ORDER_CATEGORY_FURNITURE; } // 判断订单状态是否从指定旧值变更为指定新值 public static boolean statusChangedFromTo(OrderChange c, OrderStatus from, OrderStatus to) { return c.getOldOrder().getOrderStatus() == from && c.getNewOrder().getOrderStatus() == to; } }
抽完后规则的matches方法可以简化为:
@Override public boolean matches(OrderChange orderChange) { return isRetailOrder(orderChange) && isFurnitureCategory(orderChange) && statusChangedFromTo(orderChange, null, OrderStatus.ORDER_STATUS_PAID); }
性能优化:规则分组
如果规则数量超过百级,可以对规则做前置分组提升遍历效率,比如按最常用的OrderType做第一层分组,处理OrderChange时先匹配对应OrderType的规则组,只遍历该组内的规则即可,不需要强行做多层嵌套。
极端场景适配
如果规则变更非常频繁,需要运营人员可配置,可以引入轻量级表达式引擎将规则条件配置化,存在配置文件或数据库中,不需要每次新增规则都修改代码上线。
内容的提问来源于stack exchange,提问作者onepiece
相关产品推荐
相关产品推荐

