一个状态模式的小改进

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

先来介绍一下重新优化后的状态模式的一些概念:
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(Stringname) {

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-03-21 "

时间: 2024-10-04 00:23:13

一个状态模式的小改进的相关文章

大量逻辑判断优化的思路——责任链模式复习总结及其和状态模式对比

俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及的总结知识点如下: 责任链模式概念和例子 使用的条件 和状态模式的比较分析 责任链的优缺点 纯的责任链和不纯的责任链 javax.servlet.Filter#doFilter()方法源码分析 基于AOP思想,模拟一个拦截器     前面说了一个状态模式,总结过程中发现和这个责任链的使用场景很类似,都是为了解耦大量复杂业务逻辑判断的,那么他们有什么不同呢?回忆状态模式--状态模式允许通过改变对象的内部状态而改变对象自身的行为,

传统设计模式(十)状态模式

谈到状态模式我们在这里所谈论的是一个通用的技巧:如何对对象内的状态建模----通过创建一个实例变量来持有状态值,并在方法内书写条件代码来处理不同状态.我们要把一个状态的所有行为放在一个类中.这么一来我们将行为局部化了,并使得事情更容易改变和理解. 虫子还是拿订单系统来说事了 /// <summary> /// 状态接口 /// </summary> public interface SimpleState { //检查购物车 void CheckCart(); //检查账号 voi

状态模式

假设某人一整天的流程就是"吃饭→工作→睡觉",并且他要严格按照这个流程来,那也就是说在吃饭状态下,他只能做跟吃饭有关的事情,而不能越界做工作或者睡觉有关的事情,这就涉及到了状态的管理.在写代码的时候,我们常常要根据当前的状态,来决定下一个状态并且确定当前状态下要做什么样的事情.一般来讲,我们会写一系列的if-else if-else if-else语句来实现,但是要是状态非常多的时候,这种代码不仅仅看起来十分长,而且看的人生理上也会有一种厌恶感并且看一点估计忘一点.导致这种臭代码的原因

策略模式的孪生兄弟——对状态模式的深度复习总结

俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及的总结知识点如下: 和策略模式的比较 状态模式概念和例子 应用场景 责任链模式和状态模式对比 一种代码优化的思路 java.util.Iterator里也有状态模式的影子 状态模式的优缺点 有限状态机及其应用 前面有总结--策略模式,之前早就觉得策略和状态设计模式有一些相似-- 接口的常用用法都有什么?策略设计模式复习总结 我知道策略模式是对象的行为模式,其实就是对一系列级别平等的算法的封装,它不关心算法实现,让客户端去动态的

从工作流状态机实践中总结状态模式使用心得

 作者:banq 发表时间:2003年12月07日 00:10 回复 原贴网址:http://www.jdon.com/jivejdon/thread/10981.html   状态模式好像是很简单的模式,正因为状态好像是个简单的对象,想复杂化实现设计模式就不是容易,误用情况很多. 我个人曾经设计过一个大型游戏系统的游戏状态机,游戏状态可以说是游戏设计的主要架构,但是由于系统过分复杂和时间仓促,并没有真正实现状态模式. 目前在实现一个电子政务项目中,需要进行流程状态变化,在电子政务设计中,我发现

状态模式在领域驱动设计中的使用

原文链接  作者: Tomasz Nurkiewicz  译者:陈振阳 领域驱动设计是软件开发的一种方式,问题复杂的地方通过将具体实现和一个不断改进的核心业务概念的模型连接解决.这个概念是Eric Evans提出的,http://www.domaindrivendesign.org/这个网站来促进领域驱动设计的使用.关于领域驱动设计的定义,http://dddcommunity.org/resources/ddd_terms/,这个网站有很多的描述,DDD是一种软件开发的方式: 对于大多数的软件

详解state状态模式及在C++设计模式编程中的使用实例_C 语言

每个人.事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State).最简单的一个生活中的例子就是:地铁入口处,如果你放入正确的地铁票,门就会打开让你通过.在出口处也是验票,如果正确你就可以 ok,否则就不让你通过(如果你动作野蛮,或许会有报警(Alarm),:)). 有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移). 通常我们在实现这类系统会使用到很多的 Switch/Case 语句,Case 某种状态,发生什么动作,C

详解C++设计模式编程中对状态模式的运用_C 语言

状态模式:当一个对象的内在状态发生变化时,允许改变其行为,这个对象看来像是改变了其类. 状态模式与策略模式的UML图几乎一模一样,下面列举了两者的不同: (1)可以通过环境类状态的个数来决定是使用策略模式还是状态模式. (2)策略模式的环境类自己选择一个具体策略类,具体策略类无须关心环境类:而状态模式的环境类由于外在因素需要放进一个具体状态中,以便通过其方法实现状态的切换,因此环境类和状态类之间存在一种双向的关联关系. (3)使用策略模式时,客户端需要知道所选的具体策略是哪一个,而使用状态模式时

magento 1.4.1.0 -- 新版本小改进之产品url重定向

从1.4.0.1升级到1.4.1.0后在后台发现一个对SEO有利的小改进,打开后台产品管理,选择一个产品点击进入,在url属性后可以看到这样一个复选框   默认是不可用状态,只要你一修改url的值,这个框就会变可用,你可以选择是否选中,选中的话就会在新老URL之间生成重定向,而且从字面理解生成的应该是301永久重定向.