CharlesChen's Technical Space

简单实用是我一直在软件开发追求的目标(I Focus on. Net technology, to make the greatest efforts to enjoy the best of life.)
Not the best, only better
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

.NET下的状态(State)模式 ------行为型模式

Posted on 2009-03-16 23:59  Charles Chen  阅读(532)  评论(0编辑  收藏  举报

最近学习了State状态模式,现把相关知识点总结,便于以后学习:   

对象状态影响对象的行为: 对象拥有不同的状态,往往会产生不同的行为。

一、动机

在软件构件过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。

如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?

二、意图

允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。------《设计模式》-GOF

三、结构

 

四、实例代码

 /// <summary>
    
/// 抽象类----表达状态以及依赖状态的行为
    
/// </summary>

    public abstract class State
    
{
        
public abstract void handlepush(Context c);
        
public abstract State next get;}
    }

 

具体的两个状态类     

    public class BlueState : State
    
{
        
public override void handlepush(Context c)
        
{
            Console.WriteLine(
"The State is processed By BlueState");
        }


        
public override State next
        
{
            
get return new RedState(); }
        }

    }
    public class RedState : State
    
{
        
public override void handlepush(Context c)
        
{
            Console.WriteLine(
"The State is processed By RedState");
        }


        
public override State next
        
{
            
get return new BlueState(); }
        }

    }
对应上图中的Context
    /// <summary>
    
/// 主逻辑
    
/// </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 context = new Context();
 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来根据这个型别码来执行相关操作,现在我们有更好的方式来处理。

状态和策略的异同

有人会说,状态模式和策略模式是如此的相似,何必又分开呢?关键在于状态模式和策略模式的意图,状态模式是封装对象内部的状态的,而策略模式是封装算法族的。而且状态模式往往有这种表现:状态影响着对象当前的行为,行为也会倒过来改变对象的状态,这个相互影响是发生内部,也就是说状态模式中对象的行为是由对象的状态驱动的,而策略模式却不同,每次我们往往只使用一种策略来配置当前的系统,改变策略都是由外力来改变的,要使用哪种算法是由外部对象(客户)来驱动的。