State模式与Strategy模式

    在前面的随笔中我提到了用State模式来处理绩效包的分等,后来在idior的回复中看到了关于使用State模式还是Strategy的取舍,随即温习了一下State模式(实际上是学习,用温习是假装看过)。所以将她俩之间的区别阐述如下:
    在我们设计的时候应该考虑“不变性”“可变性”,如果说一个环境中状态可能一直有变化,比如在计算包的分等的时候可能不断切换分等算法,这样就应该使用State模式。而如果我们的需求是算法一旦确定不会改变,这也正是策略模式所处理的,因为策略模式环境一旦创建,那么在环境的整个生命周期内都不会改变具体策略类。
 
    在实现上,State模式在Context类中添加了State属性,也就是说在环境被创建后还可以切换各个State类,代码如下。
/*******************************************************
 *                    状态模式
 *    状态模式与策略模式比较容易混淆,实际上她俩的区别主要
 * 在环境的可变性上,如果环境有明显的状态转换,那么就应该
 * 采用状态模式,否则选择策略模式。从这个例子中也可以看出
 * 她的实现和策略模式的实现的区别仅在状态类Context。
 * ****************************************************
*/

using System;

namespace StatePattern
{
    
/// <summary>
    
/// Class1 的摘要说明。
    
/// </summary>

    class StatePattern
    
{
        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            Context o_Context
=new Context(new RateClassifyCalculater());
            o_Context.ContextIterface();

            
//这里实现的状态的迁移,进而改变对象的行为。
            o_Context.State=new RangeClassifyCalculater();
            o_Context.ContextIterface();
            Console.ReadLine();
        }

    }


    
状态模式的抽象类

    
状态模式的实现类

    
状态模式的环境类,与策略模式的区别在与该类
}


    执行结果如下:
  

    另外环境类也可以作为参数传送给状态类,如果状态类需要就可以调节环境对象。这其实涉及到一个谁来改变状态的权衡,由环境来处理比较保险,由状态类自身决定状态的转换则更加灵活,但这种改变个人感觉好象有点失控,因为你可能在不知道的情况下环境类的状态就被改变了,所以最好在 状态子类传入Context对象的时候显式的用ref关键字,这样就可以意识到可能Context对象要改变,如果不用ref关键字,虽然效果可能一样,但是起到的警示作用是不同的

    所以在使用State和Strategy模式的时候,首要考虑的是环境状态是否是可变的

posted on 2004-12-28 11:22  纯爷们  阅读(2935)  评论(4编辑  收藏  举报

导航