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

State模式与Strategy模式    
/// Class1 的摘要说明。
State模式与Strategy模式    
/// </summary>
State模式与Strategy模式    class StatePattern
{

State模式与Strategy模式        
/// 应用程序的主入口点。
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        [STAThread]
State模式与Strategy模式        
static void Main(string[] args)
{
State模式与Strategy模式            Context o_Context
=new Context(new RateClassifyCalculater());
State模式与Strategy模式            o_Context.ContextIterface();
State模式与Strategy模式
State模式与Strategy模式            
//这里实现的状态的迁移,进而改变对象的行为。
State模式与Strategy模式
            o_Context.State=new RangeClassifyCalculater();
State模式与Strategy模式            o_Context.ContextIterface();
State模式与Strategy模式            Console.ReadLine();
State模式与Strategy模式        }

State模式与Strategy模式    }

State模式与Strategy模式

State模式与Strategy模式    
abstract public class  State
{

State模式与Strategy模式        
/// 包分等计算的主逻辑框架
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public void MainCalculateLogic()
{
State模式与Strategy模式            Console.WriteLine(
"Template Method Called");
State模式与Strategy模式            ProjectCalculater();
State模式与Strategy模式            PackageCalculater();
State模式与Strategy模式            ClassifyPackage();
State模式与Strategy模式        }

State模式与Strategy模式

State模式与Strategy模式        
/// 计算包中方案总得分的抽象方法
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        abstract public void ProjectCalculater();
State模式与Strategy模式

State模式与Strategy模式        
/// 计算最终包的得分的抽象方法
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        abstract public void PackageCalculater();
State模式与Strategy模式

State模式与Strategy模式        
/// 将计算好的包进行分等的抽象方法
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        abstract public void ClassifyPackage();
State模式与Strategy模式
State模式与Strategy模式    }

State模式与Strategy模式    
#endregion
State模式与Strategy模式

State模式与Strategy模式    
class RateClassifyCalculater:State
{

State模式与Strategy模式        
/// 比例分等计算的方案计算具体实现
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public override void ProjectCalculater()
{
State模式与Strategy模式            Console.WriteLine(
"Rate classify's calculater of project score called");
State模式与Strategy模式        }

State模式与Strategy模式

State模式与Strategy模式        
/// 比例分等计算的包分数计算具体实现
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public override void PackageCalculater()
{
State模式与Strategy模式            Console.WriteLine(
"Rate classify's calculater of package score called");
State模式与Strategy模式        }

State模式与Strategy模式

State模式与Strategy模式        
/// 比例分等计算的包分等策略具体实现
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public override void ClassifyPackage()
{
State模式与Strategy模式            Console.WriteLine(
"Rate classify's calculater of package classify logic called");
State模式与Strategy模式        }

State模式与Strategy模式    }

State模式与Strategy模式
State模式与Strategy模式    
class RangeClassifyCalculater:State
{

State模式与Strategy模式        
/// 分数区间分等计算的方案计算具体实现
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public override void ProjectCalculater()
{
State模式与Strategy模式            Console.WriteLine(
"Range classify's calculater of project score called");
State模式与Strategy模式        }

State模式与Strategy模式

State模式与Strategy模式        
/// 分数区间分等计算的包分数计算具体实现
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public override void PackageCalculater()
{
State模式与Strategy模式            Console.WriteLine(
"Range classify's calculater of package score called");
State模式与Strategy模式        }

State模式与Strategy模式

State模式与Strategy模式        
/// 分数区间分等计算的包分等策略具体实现
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public override void ClassifyPackage()
{
State模式与Strategy模式            Console.WriteLine(
"Range classify's calculater of package classify logic called");
State模式与Strategy模式        }

State模式与Strategy模式    }

State模式与Strategy模式    
#endregion
State模式与Strategy模式


State模式与Strategy模式    
/// 状态模式的环境类,用与控制状态间的转换
State模式与Strategy模式    
/// </summary>
State模式与Strategy模式    public class Context
{
State模式与Strategy模式        
private State state;
State模式与Strategy模式

State模式与Strategy模式        
/// 环境的初始化
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        
/// <param name="initState">初始化状态</param>
State模式与Strategy模式        public Context(State initState)
{
State模式与Strategy模式            
this.state=initState;
State模式与Strategy模式        }

State模式与Strategy模式

State模式与Strategy模式        
/// 环境类所维护的状态属性
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public State State
{
State模式与Strategy模式            
get
{
State模式与Strategy模式                
return this.state;
State模式与Strategy模式            }

State模式与Strategy模式            
set
{
State模式与Strategy模式                
this.state=value;
State模式与Strategy模式            }

State模式与Strategy模式        }

State模式与Strategy模式

State模式与Strategy模式        
/// 环境接口
State模式与Strategy模式        
/// </summary>
State模式与Strategy模式        public void ContextIterface()
{
State模式与Strategy模式            Console.WriteLine(
"State Context Interface called");
State模式与Strategy模式            
this.state.MainCalculateLogic();
State模式与Strategy模式        }

State模式与Strategy模式    }

State模式与Strategy模式    
#endregion
State模式与Strategy模式}

State模式与Strategy模式

    执行结果如下:
State模式与Strategy模式  

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

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

相关文章:

  • 2022-02-17
  • 2021-12-30
  • 2022-02-25
  • 2021-06-05
  • 2021-07-13
  • 2021-06-29
  • 2021-07-26
猜你喜欢
  • 2021-10-14
  • 2021-07-13
  • 2021-12-28
  • 2021-08-15
  • 2021-05-17
相关资源
相似解决方案