技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 算法 --> 一个状态模式的小改进

一个状态模式的小改进

浏览:1216次  出处信息

    设计模式中的状态模式

    

    这是标准的状态模式.其中Context管理所有状态,而每个状态都是自己的类,而状态的流转逻辑由状态自己执行.

    然后完整的状态模式实现太过”重”,而且状态流转的描述在代码上也不会是一目了然.所以我对状态模式进行了简化和优化.使其很”轻”,易于使用和实现,而且对于状态流转在代码上也能一目了然.所有的流转逻辑都能在一屏上显示出来.

    先来介绍一下重新优化后的状态模式的一些概念:

  • State:首先就是状态
  • Event:事件,事件的触发使State状态发生改变
  • Next:实为路径,就是描述一个状态 触发某个事件后会变成具体其他状态的描述
  • Status:状态实例,State只是状态的描述,而Status就状态的实例,可以被执行根据State的描述来转换成新的State
  •     代码可以见 https://github.com/zephyrleaves/easy-state

        

         我们来看一个例子就能知道他是怎么用的了

        首先我们先定义Event事件.

    1

        2

        3

        4

        5

        6

        7

        8

        9

        10

        

    public enum OrderEvent implements Event{

         //正在进行中

         DO,

         //做完了

         DONE;

        

         @Override public String getName() {

         return name();

         }

         }

        可以看到Event实际是一个枚举,列举了一系列状态相关的事件

         然后我们再定义状态

    1

        2

        3

        4

        5

        6

        7

        8

        9

        10

        11

        12

        13

        14

        15

        16

        17

        18

        19

        

    public enum OrderState implements State {

         @Next(arc = {"DO->END", "DONE->END"})

         INIT,

         @Next()

         TEST,

         END;

        

         @Override public int getValue() {

         return ordinal();

         }

        

         @Override public String getOrginName() {

         return name();

         }

        

         @Override public OrderState getStateByName(String name) {

         return valueOf(name);

         }

         }

        可以看到State本身也是枚举,而不同的是在状态上有@Next这样的annotation来描述状态流转的逻辑

         例如INIT上的@Next 表示当前如果发生DO这个Event,那么当前状态就是跳转到END上

        最后看一下串联起来的执行结果

    1

        2

        3

        4

        5

        6

        7

        8

        9

        10

        11

        12

        13

        14

        15

        16

        17

        18

        19

        20

        21

        22

        23

        24

        25

        26

        27

        28

        29

        30

        31

        32

        33

        34

        35

        36

        37

        38

        

    public class StatusTest {

         @org.testng.annotations.BeforeTest

         public void setUp() {

         }

        

         @Test

         public void testConstuructor() {

         Status status = new Status(OrderState.INIT);    //初始化状态为INIT

         Assert.assertEquals(OrderState.valueOf("INIT"), status.getCurrentState());

         }

        

         @Test

         public void testHappen() {

         Status status = new Status(OrderState.INIT);    //初始化状态为INIT

         Assert.assertEquals(OrderState.INIT, status.getCurrentState());

         HappenedResult result = status.happen(OrderEvent.DO);      //当前状态出发了DO事件

         Assert.assertEquals(result, HappenedResult.SUCCESS);       //跳转成功

         Assert.assertTrue(result.isSuccess());

         Assert.assertEquals(status.getCurrentState(), OrderState.END);    //当前状态已经跳转为END

         Assert.assertEquals(status.getPreviousState(), OrderState.INIT);  //上一个状态为INIT

        

         HappenedResult result1 = status.happen(null);               //没有发生事件

         Assert.assertEquals(result1, HappenedResult.NO_EVENT);       //提示你没事件发生

         Assert.assertEquals(status.getCurrentState(), OrderState.END);         //当前状态还是END

         Assert.assertEquals(status.getPreviousState(), OrderState.INIT);       //上一个状态还是INIT

        

         HappenedResult result2 = status.happen(OrderEvent.DONE);      //在当前状态发了DONE事件

         Assert.assertEquals(result2, HappenedResult.NO_NEXT);         //这个状态下没有定义会触发DONE事件

         Assert.assertEquals(status.getCurrentState(), OrderState.END);      //当前状态还是END

         Assert.assertEquals(status.getPreviousState(), OrderState.INIT);   //上一个状态还是INIT

        

         Status status1 = new Status(OrderState.TEST); //初始化状态为TEST

         HappenedResult result3 = status1.happen(OrderEvent.DO);             //在当前状态发了DO事件

         Assert.assertEquals(result3, HappenedResult.NO_ARC);                //这个状态下没有定义会触发的事件

         Assert.assertEquals(status1.getCurrentState(), OrderState.TEST);         //当前状态还是TEST

         Assert.assertEquals(status1.getPreviousState(), null);              //没有上一个状态

         }

         }

     

    建议继续学习:

    1. 状态模式和策略模式的比较    (阅读:1812)
    2. 一个状态模式的小改进    (阅读:1195)
    QQ技术交流群:445447336,欢迎加入!
    扫一扫订阅我的微信号:IT技术博客大学习
    © 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

    京ICP备15002552号-1