IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

一个状态模式的小改进

淘宝网通用产品团队博客 2012-03-25 21:39:19 累计浏览 2,094 次
本机暂存

    设计模式中的状态模式

    原图已失效

    这是标准的状态模式.其中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);              //没有上一个状态

        }

        }

    © 2012, 淘宝文通. 版权所有.

    同分类推荐文章

    1. 如何写好设计文档? (2026-06-23 08:00:00)
    2. Designing With Uncertainty: How AI Supercharges Probabilistic Thinking (2026-06-16 23:00:00)
    3. The Benefits Of Cognitive Inclusion In UX Research (2026-06-10 18:00:00)

    查看更多 设计 文章 →

    建议继续学习

    1. 最常被程序员们谎称读过的计算机书籍 (累计阅读 9,156)
    2. JavaScript Interface 接口的实现 (累计阅读 6,992)
    3. 用星际争霸讲解面向对象的概念 (累计阅读 5,222)
    4. 自己写的一个轻量级javascript框架的设计模式 (累计阅读 4,908)
    5. 关于架构的一句话,还有一个实例 (累计阅读 4,702)
    6. 如此理解面向对象编程 (累计阅读 4,559)
    7. 每个程序员都应该了解的知识有哪些? (累计阅读 4,477)
    8. 你从未听说过的一种编程方式 (累计阅读 4,415)
    9. 设计模式速查手册-创建型 (累计阅读 3,922)
    10. Java Worker 设计模式 (累计阅读 3,756)