状态模式简单实现 布满荆棘的人生 2022-08-26 13:10 88阅读 0赞 工作过程中,我们经常遇到一些复杂的状态转换的问题,如果我们使用传统的方式来处理状态转换,相信状态上了10多个以上的时候,每个地方都是If else判断测试的时候,你就知道痛苦了,在处理订单状态时候,10多个状态也是常有的事情,我们可以借助状态模式来解决这个问题,在多次项目过程中,使用该模式之后明显感觉状态处理要清晰得多,即使中间涉及到删减或增加一些状态 中间状态,该模式处理起来游刃有余。 状态转换,绝大多数是由于事件触发引起的,currentStatus\_\_\_event\_\_\_nextStatus,即在当前状态下发生了一个事件促使状态转移到下一个状态,设计模式中详细进行了阐述,这里我只给一个简单的实现。 ![None.gif][] public enum Status \{ wait(1) \{// 等待发送状态 @Override protected void initMap() \{ addEventTansferMap(Event.send, sended); \} \}, sended(2) \{// 已经发送状态 @Override protected void initMap() \{ addEventTansferMap(Event.confirm, confirmed); \} \}, confirmed(3) \{// 已经确认状态 @Override protected void initMap() \{\} \}; /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \* \* 共有方法 \* \* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*/ private Status(int value) \{ this.value = value; \} public int getValue()\{ return this.value; \} protected abstract void initMap();// 初始化映射事件状态映射关系 /\*\* \* 根据发生的事件得到下一个状态 \* \* @param e \* 事件 \* @return 下一个状态,如果该事件没有造成状态改变,返回null \*/ public final Status next(Event e) \{ init(); return translations.get(e); \} /\*\* \* 初始化事件与状态转换映射 \*/ private void init() \{ if (false == initialed) \{// double checked synchronized (LOCK) \{ if (false == initialed) \{ translations = new EnumMap<Event, Status>(Event.class); initMap(); initialed = true; \} \} \} \} /\*\* \* \* @param e 发生的事件 \* @param s 事件发生后转移到的状态 \*/ protected void addEventTansferMap(Event e,Status s)\{ translations.put(e, s); \} private Map<Event, Status> translations; //事件状态映射 private boolean initialed = false; // 映射是否已经初始化 private int value; //状态原始值 private Object LOCK = new Object(); // 事件枚举,可以单独作为一个类 public enum Event \{ send, // 发送事件 confirm;// 确认事件 \} public static void main(String\[\] args) \{ System.out.println("下一个状态:" + wait.next(Event.send)); System.out.println(sended.next(Event.confirm)); System.out.println(wait.next(Event.confirm)); \} \} 由以上实现可以知道,新增一个状态,新增一个事件都非常简单。第一步,在Event中新增一个事件,第二步,在Status中新增一个状态 ,第三步,新增事件和状态转移映射(覆盖initMap即可)。 在使用时只需要使用当前的发生的事件作为参数调用next即可以得到下一个状态,非常简单。 [None.gif]: /images/20220824/6443c946edce4d21a0a0c4945f3fd9f0.png
还没有评论,来说两句吧...