设计模式学习之01状态模式
主体思想:状态决定行为。
应用环境:同一对象,在状态转换过程中,行为随着状态一直在改变。
e.g. 灯初始状态是关闭的,按一下开启,再按一下关闭(不要跟我说你家的水晶变色大灯)。在这一个过程中,触发行为都是按一下开关,电灯会根据自身状态的不同调用不同的行为去实现。如果我们不适用设计模式去实现着这段逻辑,一般就是这两种实现方法吧
1.
if(灯状态==XXX) { .... } else { XXXXXXXX }
2.
switch(灯状态) { case XX: Xxxxxx break; case vv: vvvvvvvv break; default: llllll }
目前就是灯打开,关闭两个状态,咱们当然可以用这种if ,switch的方式来做。 如果实体对象状态很多的话,采用上面判断的方式,一个类方法的代码就老长老长了。ok ,那么咱们采用状态模式来看看,该如何实现。
1.分析需求,设计类
状态模式,毫无疑问,咱们需要实体类(Light),状态类(LightState)。由于状态类,会有不同状态,相同的按灯动作。因此我们这么设计。
抽象状态类:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace DesignModel_01 8 { 9 abstract class LightState 10 { 11 public abstract void PushClick(Light light); 12 } 13 }
实体类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignModel_01 { class Light { private LightState state; public Light(LightState state) { this.State = state; } public LightState State { get { return state; } set { state = value; } } public void LightClick() { this.state.PushClick(this); } } }
好了,主要工作完成,下面就是具体灯的那个状态了。目前就两种状态,打开关闭。
LightOn :
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignModel_01 { class LightOn : LightState { public override void PushClick(Light light) { Console.WriteLine("灯正在关闭ing..."); light.State = new LightOff(); Console.WriteLine("灯已经关闭..."); } } }
LightOff :
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignModel_01 { class LightOff : LightState { public override void PushClick(Light light) { Console.WriteLine("灯正在打开ing..."); light.State = new LightOpen(); Console.WriteLine("灯已经打开..."); } } }
测试man:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignModel_01 { class Program { static void Main(string[] args) { Light l = new Light(new LightOpen()); for (int i = 0; i < 10; i++) { l.LightClick(); } Console.ReadLine(); } } }
好吧,打脸了。。。。代码似乎比if,switch 判断还多。所以应对不同的业务场景,我们还是要理智的采用不同的方案。
优点
a 状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
b 所有状态相关的代码都存在于某个ConcereteState中,所以通过定义新的子类很容易地增加新的状态和转换。
c 状态模式通过把各种状态转移逻辑分不到State的子类之间,来减少相互间的依赖。
缺点
a 导致较多的ConcreteState子类
适用场景
a 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式来。
b 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态。
内容参考:
http://www.cnblogs.com/god_bless_you/archive/2010/06/06/1752517.html