State 模式
State模式在实际使用中比较多,适合”状态的切换”.因为我们经常会使用if else if else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.不只是根据状态,也有根据属性.如果某个对象的属性不同,对象的行为就不一样,这点在数据库系统中出现频率比较高,我们经常会在一个数据表的尾部,加上property属性含义的字段,用以标识记录中一些特殊性质的记录,这种属性的改变(切换)又是随时可能发生的,就有可能要使用State.文章主要分享State模式相关内容.
定义
不同的状态,不同的行为;或者说,每个状态有着相应的行为.
何时使用
State模式在实际使用中比较多,适合”状态的切换”.因为我们经常会使用 if else if else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.
不只是根据状态,也有根据属性.如果某个对象的属性不同,对象的行为就不一样,这点在数据库系统中出现频率比较高,我们经常会在一个数据表的尾部,加上property属性含义的字段,用以标识记录中一些特殊性质的记录,这种属性的改变(切换)又是随时可能发生的,就有可能要使用State.
参考网址:
http://www.jdon.com/designpatterns/designpattern_State.htm
举例来说:一个人具有生气,高兴和抓狂等状态,在这些状态下做同一个事情可能会有不同的结果,一个人的心情可能在这三种状态中循环转变。使用一个moodState类表示一个人的心情,使用mad,Happy,Angry类代表不同的心情。使用UML图表示如下所示:
适用性:在下面的两情况下均可以使用State模式:
一个对象的行为取决于它的状态,并且必须在运行时刻根据状态改变它的行为。
一个操作中含有庞大的多分支的条件豫剧,并且这些分支依赖于该对象的状态,这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构,State模式将每一个条件分支放入一个单独的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
参与者:
Context(环境,Person)定义客户感兴趣的类。
State(Moodstate):定义一个接口以封装与Context的一个特定状态相关的行为
ConcreteState Subclasses(具体状态子类,如Angry)每一个子类实现一个与Context的状态相关的行为。
他们的协作关系是:
Context将于状态相关的请求委托给当前的ConcreteState对象处理。
Context可将自身作为一个参数传递给处理该请求的状态对象,这使得状态对象在必要的时候可访问Context。
Context是客户使用的主要接口,客户可用状态对象来配置一个Context,一旦一个Context配置完毕,他的客户不再需要直接与状态对象打交道。
Context或者ConcreteState子类都可以决定哪个状态是另外那个状态的后继者,以及是在何种条件下进行状态转换。
相应的代码:
MoodState代码:
1 | package state; |
Angry代码:
1 | package state; |
Happy代码:
1 | package state; |
Mad代码:
1 | package state; |
Person代码:
1 | package state; |
Client代码:
1 | package state; |
总结
状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来,使得状态转换显式化并且可以被共享。