最近学习了State状态模式,现把相关知识点总结,便于以后学习:
对象状态影响对象的行为: 对象拥有不同的状态,往往会产生不同的行为。
一、动机
在软件构件过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?
二、意图
允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。------《设计模式》-GOF
三、结构
四、实例代码
/// 抽象类----表达状态以及依赖状态的行为
/// </summary>
public abstract class State
{
public abstract void handlepush(Context c);
public abstract State next { get;}
}
具体的两个状态类
{
public override void handlepush(Context c)
{
Console.WriteLine("The State is processed By BlueState");
}
public override State next
{
get { return new RedState(); }
}
}
{
public override void handlepush(Context c)
{
Console.WriteLine("The State is processed By RedState");
}
public override State next
{
get { return new BlueState(); }
}
}
/// 主逻辑
/// </summary>
public class Context
{
private State state = null;
public void setState(State state)
{
this.state = state;
}
public void Process()
{
state.handlepush(this);
state = state.next;
}
}
context.setState(new BlueState());
context.Process();
context.Process();
context.Process();
五、State模式的几个要点
1.State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换的解耦。
2.为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的-----即要么彻底转换过来,要么不转换。
3.如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。
为了更进一步对这个模式的理解补充如下,希望能够进一步加深理解。
什么时候使用状态模式
通过前面的阐述,我们基本上了解了状态模式的样子。那我们什么时候使用状态模式呢?来看看Martin Fowler的这个重构:Replace Type Code with State/Stategy 你有一个type code,它会影响class的行为,但你无法使用subclassing。
在你的类里面有个型别码来表示对象的当前状态,这个对象的行为通常依赖这个状态,而且在运行的时候这个状态会改变,那么对象的行为在运行的时候也要跟着改变。一般我们会使用if/else或者switch来根据这个型别码来执行相关操作,现在我们有更好的方式来处理。
状态和策略的异同
有人会说,状态模式和策略模式是如此的相似,何必又分开呢?关键在于状态模式和策略模式的意图,状态模式是封装对象内部的状态的,而策略模式是封装算法族的。而且状态模式往往有这种表现:状态影响着对象当前的行为,行为也会倒过来改变对象的状态,这个相互影响是发生内部,也就是说状态模式中对象的行为是由对象的状态驱动的,而策略模式却不同,每次我们往往只使用一种策略来配置当前的系统,改变策略都是由外力来改变的,要使用哪种算法是由外部对象(客户)来驱动的。