如何更优校验第三方传入的状态是否为当前状态的合法后续状态?
无状态机实现枚举状态的递进合法性校验
针对你提出的状态递进校验需求,完全可以通过给枚举状态绑定顺序值的方式替代大量if判断,既简洁又易维护,具体实现如下:
1. 给枚举状态显式定义顺序值
因为枚举的ordinal()方法依赖代码定义顺序,后续调整枚举顺序容易引发逻辑错误,所以建议在枚举类中手动定义每个状态的递进顺序值:
public enum CustomerStatus { CREATED(0), PROCESSED(1), UPDATED_STAGE1(2), UPDATED_STAGE2(3), UPDATED_STAGE3(4), UPDATED_STAGE4(5); private final int sequence; CustomerStatus(int sequence) { this.sequence = sequence; } public int getSequence() { return sequence; } }
这里的sequence值严格对应状态的时间递进顺序,数值越大代表状态越靠后。
2. 实现简洁的校验逻辑
在你的setNewCustomerStatus方法中,只需要比较新状态和当前状态的sequence值即可完成合法性校验:
public void setNewCustomerStatus(CustomerStatus newStatus) { // 假设当前状态存储在实例变量currentStatus中 CustomerStatus current = this.currentStatus; // 核心校验:新状态的顺序必须严格大于当前状态(不允许回退或停留在原状态) if (newStatus.getSequence() <= current.getSequence()) { throw new IllegalArgumentException( String.format("状态更新不合法:当前状态为[%s],不允许切换到[%s]", current, newStatus) ); } // 校验通过后执行状态更新 this.currentStatus = newStatus; }
方案优势
- 代码简洁:彻底消除大量if/else分支,校验逻辑仅需一行判断
- 易维护:新增状态时只需在枚举类中添加带对应sequence值的枚举项,无需修改校验逻辑
- 安全性高:显式定义的sequence不依赖枚举代码顺序,避免后续调整枚举结构引发的隐性bug
- 扩展性强:如果后续需要调整状态递进规则,仅需修改枚举中的sequence值即可
对比传统if方案
传统的if判断写法会随着状态数量增加变得极度冗长,例如:
// 传统糟糕写法示例 if (currentStatus == CustomerStatus.CREATED) { if (!List.of(PROCESSED, UPDATED_STAGE1, UPDATED_STAGE2, UPDATED_STAGE3, UPDATED_STAGE4).contains(newStatus)) { throw new IllegalArgumentException("不合法的状态切换"); } } else if (currentStatus == CustomerStatus.PROCESSED) { if (!List.of(UPDATED_STAGE1, UPDATED_STAGE2, UPDATED_STAGE3, UPDATED_STAGE4).contains(newStatus)) { throw new IllegalArgumentException("不合法的状态切换"); } } // ... 每个状态都要写对应的判断分支,维护成本极高
这种写法不仅代码冗余,新增或修改状态时还要逐一调整每个分支的判断条件,极易出错。
内容的提问来源于stack exchange,提问作者Sauchin
相关产品推荐
相关产品推荐

