设计模式——状态模式

 

 

允许一个对象在改变它的内部状态时改变他的行为。对象看起来似乎改变了它的类

 

适用性

  • 一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为
  • 一个操作中含有庞大的多分支的的条件语句,且这些分支依赖于对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的的条件结构。State模式将每一个条件分支放入一个单独的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖与其他对象而单独存在

 

参与者

Context

——定义客户感兴趣的接口

——维护一个ConcreteState子类的实例,这个实例定义当前状态

State

——定义一个接口以封装与Context的一个特定状态相关的行为

ConcreteState   Subclasses

——每一个子类实现一个与Context的一个特定状态相关的行为

 

 

 

下面,就以银行账户的状态来实现下状态者模式。银行账户根据余额可分为RedState、SilverState和GoldState。这些状态分别代表透支账号,新开账户和标准账户。账号余额在【-100.0,0.0】范围表示处于RedState状态,账号余额在【0.0 , 1000.0】范围表示处于SilverState,账号在【1000.0, 100000.0】范围表示处于GoldState状态。下面以这样的一个场景实现下状态者模式,具体实现代码如下所示:

 

 1 public class Account
 2     {
 3         public State State {get;set;}
 4         public string Owner { get; set; }
 5         public Account(string owner)
 6         {
 7             this.Owner = owner;
 8             this.State = new SilverState(0.0, this);
 9         }
10 
11         public double Balance { get {return State.Balance; }} // 余额
12         // 存钱
13         public void Deposit(double amount)
14         {
15             State.Deposit(amount);
16             Console.WriteLine("存款金额为 {0:C}——", amount);
17             Console.WriteLine("账户余额为 =:{0:C}", this.Balance);
18             Console.WriteLine("账户状态为: {0}", this.State.GetType().Name);
19             Console.WriteLine();
20         }
21 
22         // 取钱
23         public void Withdraw(double amount)
24         {
25             State.Withdraw(amount);
26              Console.WriteLine("取款金额为 {0:C}——",amount);
27             Console.WriteLine("账户余额为 =:{0:C}", this.Balance);
28             Console.WriteLine("账户状态为: {0}", this.State.GetType().Name);
29             Console.WriteLine();
30         }
31 
32         // 获得利息
33         public void PayInterest()
34         {
35             State.PayInterest();
36             Console.WriteLine("Interest Paid --- ");
37             Console.WriteLine("账户余额为 =:{0:C}", this.Balance);
38             Console.WriteLine("账户状态为: {0}", this.State.GetType().Name);
39             Console.WriteLine();
40         }
41     }

 

 1   // 抽象状态类
 2     public abstract class State
 3     {
 4         // Properties
 5         public Account Account { get; set; }
 6         public double Balance { get; set; } // 余额
 7         public double Interest { get; set; } // 利率
 8         public double LowerLimit { get; set; } // 下限
 9         public double UpperLimit { get; set; } // 上限
10 
11         public abstract void Deposit(double amount); // 存款
12         public abstract void Withdraw(double amount); // 取钱
13         public abstract void PayInterest(); // 获得的利息
14     }

 

 

 1  // Red State意味着Account透支了
 2     public class RedState : State
 3     {
 4         public RedState(State state)
 5         {
 6             // Initialize
 7             this.Balance = state.Balance;
 8             this.Account = state.Account;
 9             Interest = 0.00;
10             LowerLimit = -100.00;
11             UpperLimit = 0.00;
12         }
13 
14         // 存款
15         public override void Deposit(double amount)
16         {
17             Balance += amount;
18             StateChangeCheck();
19         }
20         // 取钱
21         public override void Withdraw(double amount)
22         {
23             Console.WriteLine("没有钱可以取了!");
24         }
25 
26         public override void PayInterest()
27         {
28             // 没有利息
29         }
30 
31         private void StateChangeCheck()
32         {
33             if (Balance > UpperLimit)
34             {
35                 Account.State = new SilverState(this);
36             }
37         }
38     }

 

 

 1  // Silver State意味着没有利息得
 2     public class SilverState :State
 3     {
 4         public SilverState(State state)
 5             : this(state.Balance, state.Account)
 6         { 
 7         }
 8 
 9         public SilverState(double balance, Account account)
10         {
11             this.Balance = balance;
12             this.Account = account;
13             Interest = 0.00;
14             LowerLimit = 0.00;
15             UpperLimit = 1000.00;
16         }
17 
18         public override void Deposit(double amount)
19         {
20             Balance += amount;
21             StateChangeCheck();
22         }
23         public override void Withdraw(double amount)
24         {
25             Balance -= amount;
26             StateChangeCheck();
27         }
28 
29         public override void PayInterest()
30         {
31             Balance += Interest * Balance;
32             StateChangeCheck();
33         }
34 
35         private void StateChangeCheck()
36         {
37             if (Balance < LowerLimit)
38             {
39                 Account.State = new RedState(this);
40             }
41             else if (Balance > UpperLimit)
42             {
43                 Account.State = new GoldState(this);
44             }
45         }     
46     }

 

 

 1  // Gold State意味着有利息状态
 2     public class GoldState : State
 3     {
 4         public GoldState(State state)
 5         {
 6             this.Balance = state.Balance;
 7             this.Account = state.Account;
 8             Interest = 0.05;
 9             LowerLimit = 1000.00;
10             UpperLimit = 1000000.00;
11         }
12         // 存钱
13         public override void Deposit(double amount)
14         {
15             Balance += amount;
16             StateChangeCheck();
17         }
18         // 取钱
19         public override void Withdraw(double amount)
20         {
21             Balance -= amount;
22             StateChangeCheck();
23         }
24         public override void PayInterest()
25         {
26             Balance += Interest * Balance;
27             StateChangeCheck();
28         }
29 
30         private void StateChangeCheck()
31         {
32             if (Balance < 0.0)
33             {
34                 Account.State = new RedState(this);
35             }
36             else if (Balance < LowerLimit)
37             {
38                 Account.State = new SilverState(this);
39             }
40         }
41     }

 

 

 1  class App
 2     {
 3         static void Main(string[] args)
 4         {
 5             // 开一个新的账户
 6             Account account = new Account("Learning Hard");
 7 
 8             // 进行交易
 9             // 存钱
10             account.Deposit(1000.0);
11             account.Deposit(200.0);
12             account.Deposit(600.0);
13 
14             // 付利息
15             account.PayInterest();
16 
17             // 取钱
18             account.Withdraw(2000.00);
19             account.Withdraw(500.00);
20             
21             // 等待用户输入
22             Console.ReadKey();
23         }
24     }
25 }

 

 

从上图可以发现,进行存取款交易,会影响到Account内部的状态,由于状态的改变,从而影响到Account类行为的改变,而且这些操作都是发生在运行时的。

 

应用状态者模式完善中介者模式方案

 

  1 // 抽象牌友类
  2     public abstract class AbstractCardPartner
  3     {
  4         public int MoneyCount { get; set; }
  5 
  6         public AbstractCardPartner()
  7         {
  8             MoneyCount = 0;
  9         }
 10 
 11         public abstract void ChangeCount(int Count, AbstractMediator mediator);
 12     }
 13 
 14     // 牌友A类
 15     public class ParterA : AbstractCardPartner
 16     {
 17         // 依赖与抽象中介者对象
 18         public override void ChangeCount(int Count, AbstractMediator mediator)
 19         {
 20             mediator.ChangeCount(Count);
 21         }
 22     }
 23 
 24     // 牌友B类
 25     public class ParterB : AbstractCardPartner
 26     {
 27         // 依赖与抽象中介者对象
 28         public override void ChangeCount(int Count, AbstractMediator mediator)
 29         {
 30             mediator.ChangeCount(Count);
 31         }
 32     }
 33 
 34     // 抽象状态类
 35     public abstract class State
 36     {
 37         protected AbstractMediator meditor;
 38         public abstract void ChangeCount(int count);
 39     }
 40 
 41     // A赢状态类
 42     public class AWinState : State
 43     {
 44         public AWinState(AbstractMediator concretemediator)
 45         {
 46             this.meditor = concretemediator;
 47         }
 48 
 49         public override void ChangeCount(int count)
 50         {
 51             foreach (AbstractCardPartner p in meditor.list)
 52             {
 53                 ParterA a = p as ParterA;
 54                 // 
 55                 if (a != null)
 56                 {
 57                     a.MoneyCount += count;
 58                 }
 59                 else
 60                 {
 61                     p.MoneyCount -= count;
 62                 }
 63             }
 64         }
 65     }
 66 
 67     // B赢状态类
 68     public class BWinState : State
 69     {
 70         public BWinState(AbstractMediator concretemediator)
 71         {
 72             this.meditor = concretemediator;
 73         }
 74 
 75         public override void ChangeCount(int count)
 76         {
 77             foreach (AbstractCardPartner p in meditor.list)
 78             {
 79                 ParterB b = p as ParterB;
 80                 // 如果集合对象中时B对象,则对B的钱添加
 81                 if (b != null)
 82                 {
 83                     b.MoneyCount += count;
 84                 }
 85                 else
 86                 {
 87                     p.MoneyCount -= count;
 88                 }
 89             }
 90         }
 91     }
 92 
 93     // 初始化状态类
 94     public class InitState : State
 95     {
 96         public InitState()
 97         {
 98             Console.WriteLine("游戏才刚刚开始,暂时还有玩家胜出");
 99         }
100 
101         public override void ChangeCount(int count)
102         {
103             // 
104             return;
105         }
106     }
107 
108     // 抽象中介者类
109     public abstract class AbstractMediator
110     {
111         public List<AbstractCardPartner> list = new List<AbstractCardPartner>();
112 
113         public State State { get; set; }
114 
115         public AbstractMediator(State state)
116         {
117             this.State = state;
118         }
119 
120         public void Enter(AbstractCardPartner partner)
121         {
122             list.Add(partner);
123         }
124 
125         public void Exit(AbstractCardPartner partner)
126         {
127             list.Remove(partner);
128         }
129 
130         public void ChangeCount(int count)
131         {
132             State.ChangeCount(count);
133         }
134     }
135 
136     // 具体中介者类
137     public class MediatorPater : AbstractMediator
138     {
139         public MediatorPater(State initState)
140             : base(initState)
141         { }
142     }
143 
144     class Program
145     {
146         static void Main(string[] args)
147         {
148             AbstractCardPartner A = new ParterA();
149             AbstractCardPartner B = new ParterB();
150             // 初始钱
151             A.MoneyCount = 20;
152             B.MoneyCount = 20;
153 
154             AbstractMediator mediator = new MediatorPater(new InitState());
155 
156             // A,B玩家进入平台进行游戏
157             mediator.Enter(A);
158             mediator.Enter(B);
159 
160             // A赢了
161             mediator.State = new AWinState(mediator);
162             mediator.ChangeCount(5);
163             Console.WriteLine("A 现在的钱是:{0}", A.MoneyCount);// 应该是25
164             Console.WriteLine("B 现在的钱是:{0}", B.MoneyCount); // 应该是15
165 
166             // B 赢了
167             mediator.State = new BWinState(mediator);
168             mediator.ChangeCount(10);
169             Console.WriteLine("A 现在的钱是:{0}", A.MoneyCount);// 应该是25
170             Console.WriteLine("B 现在的钱是:{0}", B.MoneyCount); // 应该是15
171             Console.Read();
172         }
173     }

 

状态者模式是对对象状态的抽象,从而把对象中对状态复杂的判断逻辑已到各个状态类里面,从而简化逻辑判断。在下一篇文章将分享我对策略模式的理解。

 

posted on 2018-06-08 10:17  勤学才是王道  阅读(289)  评论(0编辑  收藏  举报

导航