枚举(Enum)不只是常量:打造带有业务逻辑的强类型状态机
枚举Enum不只是常量打造带有业务逻辑的强类型状态机在Java等编程语言中枚举Enum通常被视为简单的常量集合但实际上它们是功能强大的工具可以构建带有业务逻辑的强类型状态机。本文将展示如何通过给枚举类添加方法实现一个资金操作审批的状态流转系统体现枚举在业务逻辑中的强大能力。传统枚举的局限性传统上枚举被定义为简单的常量集合java1public enum ApprovalStatus { 2 PENDING, APPROVED, REJECTED, CANCELLED 3} 4这种用法虽然简单但缺乏行为表达能力状态之间的流转逻辑需要分散在多个服务类中实现导致代码难以维护和理解。枚举作为状态机的优势将枚举升级为状态机可以带来以下优势强类型安全编译器确保所有状态转换都是合法的自描述性状态转换逻辑直接关联到状态本身集中管理所有状态相关逻辑集中在一处可维护性新增状态或修改流转规则更方便实现资金操作审批状态机让我们实现一个资金操作审批的状态机包含以下状态和转换java1import java.math.BigDecimal; 2 3public enum ApprovalStatus { 4 // 待审批状态 5 PENDING { 6 Override 7 public ApprovalStatus approve(ApprovalContext context) { 8 if (context.getAmount().compareTo(BigDecimal.valueOf(10000)) 0) { 9 return NEED_MANAGER_APPROVAL; 10 } 11 return APPROVED; 12 } 13 14 Override 15 public ApprovalStatus reject(ApprovalContext context) { 16 return REJECTED; 17 } 18 }, 19 20 // 需要经理审批 21 NEED_MANAGER_APPROVAL { 22 Override 23 public ApprovalStatus approve(ApprovalContext context) { 24 // 经理审批逻辑 25 if (context.getManagerLevel() 2) { 26 return APPROVED; 27 } 28 return PENDING; // 降级需要重新审批 29 } 30 31 Override 32 public ApprovalStatus reject(ApprovalContext context) { 33 return REJECTED; 34 } 35 }, 36 37 // 已批准 38 APPROVED { 39 Override 40 public ApprovalStatus cancel(ApprovalContext context) { 41 if (context.getOperationDate().isBefore(context.getCurrentDate().minusDays(1))) { 42 return CANNOT_CANCEL; 43 } 44 return CANCELLED; 45 } 46 }, 47 48 // 已拒绝 49 REJECTED { 50 // 拒绝状态不可再审批或取消 51 }, 52 53 // 已取消 54 CANCELLED { 55 // 取消状态不可再操作 56 }, 57 58 // 不可取消状态 59 CANNOT_CANCEL { 60 // 不可操作状态 61 }; 62 63 // 状态转换方法 64 public ApprovalStatus approve(ApprovalContext context) { 65 throw new IllegalStateException(Cannot approve from state: this); 66 } 67 68 public ApprovalStatus reject(ApprovalContext context) { 69 throw new IllegalStateException(Cannot reject from state: this); 70 } 71 72 public ApprovalStatus cancel(ApprovalContext context) { 73 throw new IllegalStateException(Cannot cancel from state: this); 74 } 75 76 // 判断当前状态是否可以转换到目标状态 77 public boolean canTransitionTo(ApprovalStatus targetStatus) { 78 // 实现状态转换规则检查 79 // 这里可以添加更复杂的业务规则 80 switch (this) { 81 case PENDING: 82 return targetStatus APPROVED || targetStatus REJECTED || 83 targetStatus NEED_MANAGER_APPROVAL; 84 case NEED_MANAGER_APPROVAL: 85 return targetStatus APPROVED || targetStatus REJECTED || 86 targetStatus PENDING; 87 case APPROVED: 88 return targetStatus CANCELLED || targetStatus CANNOT_CANCEL; 89 default: 90 return false; 91 } 92 } 93} 94 95// 审批上下文类 96class ApprovalContext { 97 private BigDecimal amount; 98 private int managerLevel; 99 private LocalDate operationDate; 100 private LocalDate currentDate; 101 102 // 构造方法、getter和setter省略 103} 104使用状态机进行审批操作java1import java.math.BigDecimal; 2import java.time.LocalDate; 3 4public class ApprovalWorkflow { 5 public static void main(String[] args) { 6 ApprovalContext context new ApprovalContext(); 7 context.setAmount(new BigDecimal(15000)); 8 context.setManagerLevel(2); 9 context.setOperationDate(LocalDate.now()); 10 context.setCurrentDate(LocalDate.now()); 11 12 ApprovalStatus currentStatus ApprovalStatus.PENDING; 13 14 System.out.println(初始状态: currentStatus); 15 16 try { 17 // 尝试审批 18 currentStatus currentStatus.approve(context); 19 System.out.println(审批后状态: currentStatus); 20 21 // 检查是否可以取消 22 if (currentStatus.canTransitionTo(ApprovalStatus.CANCELLED)) { 23 currentStatus currentStatus.cancel(context); 24 System.out.println(取消后状态: currentStatus); 25 } 26 } catch (IllegalStateException e) { 27 System.out.println(状态转换失败: e.getMessage()); 28 } 29 } 30} 31高级实现技巧1. 使用策略模式处理复杂逻辑对于更复杂的业务规则可以在枚举方法中委托给策略对象java1public enum ApprovalStatus { 2 PENDING { 3 private final ApprovalStrategy strategy new LargeAmountApprovalStrategy(); 4 5 Override 6 public ApprovalStatus approve(ApprovalContext context) { 7 return strategy.handleApproval(this, context); 8 } 9 }, 10 // 其他状态... 11} 12 13interface ApprovalStrategy { 14 ApprovalStatus handleApproval(ApprovalStatus current, ApprovalContext context); 15} 16 17class LargeAmountApprovalStrategy implements ApprovalStrategy { 18 Override 19 public ApprovalStatus handleApproval(ApprovalStatus current, ApprovalContext context) { 20 if (context.getAmount().compareTo(BigDecimal.valueOf(10000)) 0) { 21 return ApprovalStatus.NEED_MANAGER_APPROVAL; 22 } 23 return ApprovalStatus.APPROVED; 24 } 25} 262. 添加状态转换历史记录java1public enum ApprovalStatus { 2 // ... 其他代码同上 3 4 public ListApprovalStatus getTransitionHistory() { 5 // 实现状态转换历史记录逻辑 6 // 可以通过上下文对象传递历史记录 7 return context.getTransitionHistory(); 8 } 9} 103. 使用枚举实现状态模式将每个状态实现为一个单独的类通过枚举统一管理java1public enum ApprovalStatus { 2 PENDING(new PendingState()), 3 APPROVED(new ApprovedState()), 4 // 其他状态... 5 ; 6 7 private final State state; 8 9 ApprovalStatus(State state) { 10 this.state state; 11 } 12 13 public ApprovalStatus approve(ApprovalContext context) { 14 return state.approve(context, this); 15 } 16 17 interface State { 18 ApprovalStatus approve(ApprovalContext context, ApprovalStatus current); 19 // 其他状态操作... 20 } 21 22 static class PendingState implements State { 23 Override 24 public ApprovalStatus approve(ApprovalContext context, ApprovalStatus current) { 25 // 实现待审批状态的审批逻辑 26 return ...; 27 } 28 } 29} 30实际应用中的考虑因素线程安全确保枚举方法是无状态的或线程安全的序列化枚举默认是可序列化的但要注意上下文对象的序列化测试为每个状态转换编写单元测试扩展性考虑使用工厂模式或策略模式处理复杂逻辑文档为每个状态和方法添加详细的JavaDoc结论通过为枚举添加方法我们可以创建强大的状态机将业务逻辑直接关联到状态本身。这种模式提供了更好的类型安全更集中的业务逻辑管理更清晰的代码结构更易于维护和扩展的系统在资金操作审批、订单处理、工作流管理等场景中这种模式能显著提高代码质量和可维护性。枚举远不止是简单的常量集合它们是构建健壮业务逻辑的强大工具。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2564184.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!