大连仟亿科技
客服中心
  • 电话
  • 电话咨询:0411-39943997
  • 手机
  • 手机咨询:15840979770
    手机咨询:13889672791
网络营销 >更多
您现在的位置:仟亿科技 > 新闻中心 > 常见问题

设计模式中的状态模式的一个小改进

作者:billionnet 发布于:2012/5/6 20:14:17 点击量:

 

设计模式中的状态模式

 

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

}

}

 



分享到:


评论加载中...
内容:
评论者: 验证码:
  

Copyright@ 2011-2017 版权所有:大连仟亿科技有限公司 辽ICP备11013762-1号   google网站地图   百度网站地图   网站地图

公司地址:大连市沙河口区中山路692号辰熙星海国际2215 客服电话:0411-39943997 QQ:2088827823 42286563

法律声明:未经许可,任何模仿本站模板、转载本站内容等行为者,本站保留追究其法律责任的权利! 隐私权政策声明