设计模式State 的一个例子
(引自http://blog.csdn.net/airhand/archive/2004/08/27/86405.aspx?中的部分章节)
这个实例比较长,我简单说明一下,这是一个自动售货机的例子,客户可以投掷面值5、10、25的硬币,货物价值25。每当客户投了硬币就打印投的钱数和,如果够了25,就提示货物售出。 state是个抽象类,它派生了5、10、15、20、25几种钱数和的类(也就是所有可能的钱数和),由于它们都是从STATE继承的,所以它们都有一个STATE类型的静态成员state作为状态的标识(你可以把它想象成全局变量),每个类都接收投入5、10、25面值的硬币,对应的方法是 public virtual void AddNickel(VendingMachine vm) { } public virtual void AddDime(VendingMachine vm) { } public virtual void AddQuarter(VendingMachine vm) { } 虽然方法一样,但是每个类内部实现的状态跃迁是不一样的,比如5元的类,接收10元后state就跃迁到了15元,以此类推。 仔细看看吧,这是一个非常有意思的实例。不过说实话,这样实现程序确实太累了,也许在别的应用中可以降低程序员的负担,不过我还没发现(有的话告诉我)。 另外如果有100种状态,有10种路径,难道每个状态都要继承(100×10)?那coding起来岂不是太累,而且代码不要太长啊,唉,当程序员真不容易啊...
using System;
abstract class State { ? public virtual void AddNickel(VendingMachine vm) {}
? public virtual void AddDime(VendingMachine vm) {}
? public virtual void AddQuarter(VendingMachine vm) {}
? protected virtual void ChangeState(VendingMachine vm, State s) { ??? vm.ChangeState(s); ? } }
class VendingMachine { ? private State state; ? public VendingMachine() { ??? Console.WriteLine("The Vending Machine is now online: product costs 25c"); ??? state = Start.Instance(); ? }
? public void ChangeState(State to) { ??? state = to; ? }
? public void Vend() { // 发饮料 ??? Console.WriteLine("Dispensing product...Thank you!"); ? }
? public void AddNickel() { ??? state.AddNickel(this); ? }
? public void AddDime() { ??? state.AddDime(this); ? }
? public void AddQuarter() { ??? state.AddQuarter(this); ? } }
class Start : State { ? private static State state = new Start(); ? private Start() { ? }
? public static State Instance() { // singleton逻辑 ??? Console.WriteLine("Credit: 0c"); ??? return state; ? }
? public override void AddNickel(VendingMachine vm) { ??? ChangeState(vm, Five.Instance()); ? }
? public override void AddDime(VendingMachine vm) { ??? ChangeState(vm, Ten.Instance()); ? }
? public override void AddQuarter(VendingMachine vm) { ??? vm.Vend(); ? } }
class Five : State { ? private static State state = new Five(); ? private Five() { ? }
? public static State Instance() { // singleton 逻辑 ??? Console.WriteLine("Credit: 5c"); ??? return state; ? }
? public override void AddNickel(VendingMachine vm) { ??? ChangeState(vm, Ten.Instance()); ? }
? public override void AddDime(VendingMachine vm) { ??? ChangeState(vm, Fifteen.Instance()); ? }
? public override void AddQuarter(VendingMachine vm) { ??? vm.Vend(); ??? ChangeState(vm, Start.Instance()); // no change returned :-) ? } }
class Ten : State { ? private static State state = new Ten(); ? private Ten() { ? }
? public static State Instance() { // singleton 逻辑 ??? Console.WriteLine("Credit: 10c"); ??? return state; ? }
? public override void AddNickel(VendingMachine vm) { ??? ChangeState(vm, Fifteen.Instance()); ? }
? public override void AddDime(VendingMachine vm) { ??? ChangeState(vm, Twenty.Instance()); ? }
? public override void AddQuarter(VendingMachine vm) { ??? vm.Vend(); ??? ChangeState(vm, Start.Instance()); // no change returned :-) ? } }
class Fifteen : State { ? private static State state = new Fifteen(); ? private Fifteen() { ? }
? public static State Instance() { // singleton 逻辑 ??? Console.WriteLine("Credit: 15c"); ??? return state; ? }
? public override void AddNickel(VendingMachine vm) { ??? ChangeState(vm, Twenty.Instance()); ? }
? public override void AddDime(VendingMachine vm) { ??? vm.Vend(); ??? ChangeState(vm, Start.Instance()); ? }
? public override void AddQuarter(VendingMachine vm) { ??? vm.Vend(); ??? ChangeState(vm, Start.Instance()); // no change returned :-) ? } }
class Twenty : State { ? private static State state = new Twenty(); ? private Twenty() { ? }
? public static State Instance() { // singleton 逻辑 ??? Console.WriteLine("Credit: 20c"); ??? return state; ? }
? public override void AddNickel(VendingMachine vm) { ??? vm.Vend(); ??? ChangeState(vm, Start.Instance()); ? }
? public override void AddDime(VendingMachine vm) { ??? vm.Vend(); ??? ChangeState(vm, Start.Instance()); ? }
? public override void AddQuarter(VendingMachine vm) { ??? vm.Vend(); ??? ChangeState(vm, Start.Instance()); // no change returned :-) ? } }
class Application { ? public static void Main() { ??? int coin = 0; ??? string input = null; ??? VendingMachine vm = new VendingMachine(); ??? while (true) { ????? Console.Write("Insert a coin (5, 10, 25): "); ????? input = Console.ReadLine(); ????? coin = Int32.Parse(input); ????? switch (coin) { ??????? case 5: ????????? vm.AddNickel(); ????????? break; ??????? case 10: ????????? vm.AddDime(); ????????? break; ??????? case 25: ????????? vm.AddQuarter(); ????????? break; ??????? default: ????????? break; ????? } ??? } ? } }

|