State模式与Strategy模式
在前面的随笔中我提到了用State模式来处理绩效包的分等,后来在idior的回复中看到了关于使用State模式还是Strategy的取舍,随即温习了一下State模式(实际上是学习,用温习是假装看过)。所以将她俩之间的区别阐述如下:
在我们设计的时候应该考虑“不变性”与“可变性”,如果说一个环境中状态可能一直有变化,比如在计算包的分等的时候可能不断切换分等算法,这样就应该使用State模式。而如果我们的需求是算法一旦确定不会改变,这也正是策略模式所处理的,因为策略模式环境一旦创建,那么在环境的整个生命周期内都不会改变具体策略类。
在实现上,State模式在Context类中添加了State属性,也就是说在环境被创建后还可以切换各个State类,代码如下。
执行结果如下:
另外环境类也可以作为参数传送给状态类,如果状态类需要就可以调节环境对象。这其实涉及到一个谁来改变状态的权衡,由环境来处理比较保险,由状态类自身决定状态的转换则更加灵活,但这种改变个人感觉好象有点失控,因为你可能在不知道的情况下环境类的状态就被改变了,所以最好在 状态子类传入Context对象的时候显式的用ref关键字,这样就可以意识到可能Context对象要改变,如果不用ref关键字,虽然效果可能一样,但是起到的警示作用是不同的。
所以在使用State和Strategy模式的时候,首要考虑的是环境状态是否是可变的。
在我们设计的时候应该考虑“不变性”与“可变性”,如果说一个环境中状态可能一直有变化,比如在计算包的分等的时候可能不断切换分等算法,这样就应该使用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。
* *****************************************************/
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模式的时候,首要考虑的是环境状态是否是可变的。