核心业务包装类的可读性取决于流程控制是否清晰表达“谁在什么时候做什么、为什么这么做”;应采用状态机模型替代嵌套判断,封装命令对象,明确方法契约,并分离正向流与异常流。

核心业务包装类的可读性,不取决于代码行数多少,而在于流程控制是否清晰表达“谁在什么时候做什么、为什么这么做”。标准流程控制设计的本质,是把隐含的执行逻辑显性化、结构化、契约化——让每个方法调用都像阅读说明书一样自然。
用状态机模型替代嵌套条件判断
当包装类涉及多阶段流转(如订单包装→风控校验→库存锁定→物流分配),硬编码 if-else 或 switch 容易导致分支爆炸、责任模糊。应采用轻量级状态机:定义明确的状态枚举(如 PENDING、VALIDATED、LOCKED、SHIPPED),每个状态对应单一职责的方法(如 onValidated()、onLocked()),状态迁移由统一的 transitionTo(NextState) 控制,并强制校验前置条件与后置副作用。
- 避免在 process() 里写 “if (status == X) { ... } else if (status == Y) { ... }”
- 状态变更必须触发日志记录与监控埋点,且不可逆操作(如扣减库存)只允许在指定状态下调用
- 对外暴露的 API 只接受事件(如 submitForValidation()),不暴露中间状态字段
将流程步骤封装为不可变的命令对象
把每个关键动作(如“生成运单号”“推送履约消息”“更新主数据”)抽离为独立的、命名清晰的命令类,例如 GenerateWaybillCommand、NotifyFulfillmentCommand。这些类实现统一接口 Command
- 命令类无 public 字段,所有参数通过构造函数注入并标记为 final
- 执行失败时统一抛出带业务语义的异常(如 WaybillGenerationFailedException),而非 RuntimeException
- 流程编排层(如包装类的 fulfill() 方法)只负责按序调用命令,不掺杂业务规则
流程边界由显式契约定义,而非隐式约定
可读性差常源于“这个方法到底改了什么?有没有副作用?是否线程安全?”。应在方法签名和 JavaDoc 中明确声明流程契约:
- 用 @Precondition 和 @Postcondition 注解说明调用前提与结果保证(如 “调用前订单必须已支付”、“返回后库存占用量+1”)
- 标注线程行为:@ThreadSafe、@NotThreadSafe 或 @GuardedBy("lock")
- 对可能阻塞的操作(如远程调用)注明超时策略与降级方式(如 “超时3s,降级返回默认运单号”)
拒绝“万能入口”,拆分正向流与异常流
一个叫 handleOrder() 的方法既处理成功路径,又兜底重试、补偿、告警,必然难以理解。应分离关注点:
- 主流程:只做确定性操作,无 try-catch,失败直接向上抛出
- 协调器类(如 OrderFulfillmentOrchestrator)负责捕获异常、触发补偿、决定重试策略
- 可观测入口(如 traceableFulfill(OrderId))包装主流程,自动注入链路ID、记录耗时、上报指标











