状态者模式

一、引言

  在上一篇文章介绍到可以使用状态者模式和观察者模式来解决中介者模式存在的问题,在本文中将首先通过一个银行账户的例子来解释状态者模式,通过这个例子使大家可以对状态者模式有一个清楚的认识,接着,再使用状态者模式来解决上一篇文章中提出的问题。

二、状态者模式的介绍

  每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时,那么就会对应很多的行为。那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码。这样的设计显然违背了开闭原则。状态模式正是用来解决这样的问题的。状态模式将每种状态对应的行为抽象出来成为单独新的对象,这样状态的变化不再依赖于对象内部的行为。

2.1 状态者模式的定义

  上面对状态模式做了一个简单的介绍,这里给出状态模式的定义。

  状态模式——允许一个对象在其内部状态改变时自动改变其行为,对象看起来就像是改变了它的类。

2.2 状态者模式的结构

  既然状态者模式是对已有对象的状态进行抽象,则自然就有抽象状态者类和具体状态者类,而原来已有对象需要保存抽象状态者类的引用,通过调用抽象状态者的行为来改变已有对象的行为。经过上面的分析,状态者模式的结构图也就很容易理解了,具体结构图如下图示。

  

  从上图可知,状态者模式涉及以下三个角色:

  • Account类:维护一个State类的一个实例,该实例标识着当前对象的状态。
  • State类:抽象状态类,定义了一个具体状态类需要实现的行为约定。
  • SilveStater、GoldState和RedState类:具体状态类,实现抽象状态类的每个行为。

2.3 状态者模式的实现

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

  1 namespace StatePatternSample
  2 {
  3     public class Account
  4     {
  5         public State State {get;set;}
  6         public string Owner { get; set; }
  7         public Account(string owner)
  8         {
  9             this.Owner = owner;
 10             this.State = new SilverState(0.0, this);
 11         }
 12
 13         public double Balance { get {return State.Balance; }} // 余额
 14         // 存钱
 15         public void Deposit(double amount)
 16         {
 17             State.Deposit(amount);
 18             Console.WriteLine("存款金额为 {0:C}——", amount);
 19             Console.WriteLine("账户余额为 =:{0:C}", this.Balance);
 20             Console.WriteLine("账户状态为: {0}", this.State.GetType().Name);
 21             Console.WriteLine();
 22         }
 23
 24         // 取钱
 25         public void Withdraw(double amount)
 26         {
 27             State.Withdraw(amount);
 28              Console.WriteLine("取款金额为 {0:C}——",amount);
 29             Console.WriteLine("账户余额为 =:{0:C}", this.Balance);
 30             Console.WriteLine("账户状态为: {0}", this.State.GetType().Name);
 31             Console.WriteLine();
 32         }
 33
 34         // 获得利息
 35         public void PayInterest()
 36         {
 37             State.PayInterest();
 38             Console.WriteLine("Interest Paid --- ");
 39             Console.WriteLine("账户余额为 =:{0:C}", this.Balance);
 40             Console.WriteLine("账户状态为: {0}", this.State.GetType().Name);
 41             Console.WriteLine();
 42         }
 43     }
 44
 45     // 抽象状态类
 46     public abstract class State
 47     {
 48         // Properties
 49         public Account Account { get; set; }
 50         public double Balance { get; set; } // 余额
 51         public double Interest { get; set; } // 利率
 52         public double LowerLimit { get; set; } // 下限
 53         public double UpperLimit { get; set; } // 上限
 54
 55         public abstract void Deposit(double amount); // 存款
 56         public abstract void Withdraw(double amount); // 取钱
 57         public abstract void PayInterest(); // 获得的利息
 58     }
 59
 60     // Red State意味着Account透支了
 61     public class RedState : State
 62     {
 63         public RedState(State state)
 64         {
 65             // Initialize
 66             this.Balance = state.Balance;
 67             this.Account = state.Account;
 68             Interest = 0.00;
 69             LowerLimit = -100.00;
 70             UpperLimit = 0.00;
 71         }
 72
 73         // 存款
 74         public override void Deposit(double amount)
 75         {
 76             Balance += amount;
 77             StateChangeCheck();
 78         }
 79         // 取钱
 80         public override void Withdraw(double amount)
 81         {
 82             Console.WriteLine("没有钱可以取了!");
 83         }
 84
 85         public override void PayInterest()
 86         {
 87             // 没有利息
 88         }
 89
 90         private void StateChangeCheck()
 91         {
 92             if (Balance > UpperLimit)
 93             {
 94                 Account.State = new SilverState(this);
 95             }
 96         }
 97     }
 98
 99     // Silver State意味着没有利息得
100     public class SilverState :State
101     {
102         public SilverState(State state)
103             : this(state.Balance, state.Account)
104         {
105         }
106
107         public SilverState(double balance, Account account)
108         {
109             this.Balance = balance;
110             this.Account = account;
111             Interest = 0.00;
112             LowerLimit = 0.00;
113             UpperLimit = 1000.00;
114         }
115
116         public override void Deposit(double amount)
117         {
118             Balance += amount;
119             StateChangeCheck();
120         }
121         public override void Withdraw(double amount)
122         {
123             Balance -= amount;
124             StateChangeCheck();
125         }
126
127         public override void PayInterest()
128         {
129             Balance += Interest * Balance;
130             StateChangeCheck();
131         }
132
133         private void StateChangeCheck()
134         {
135             if (Balance < LowerLimit)
136             {
137                 Account.State = new RedState(this);
138             }
139             else if (Balance > UpperLimit)
140             {
141                 Account.State = new GoldState(this);
142             }
143         }
144     }
145
146     // Gold State意味着有利息状态
147     public class GoldState : State
148     {
149         public GoldState(State state)
150         {
151             this.Balance = state.Balance;
152             this.Account = state.Account;
153             Interest = 0.05;
154             LowerLimit = 1000.00;
155             UpperLimit = 1000000.00;
156         }
157         // 存钱
158         public override void Deposit(double amount)
159         {
160             Balance += amount;
161             StateChangeCheck();
162         }
163         // 取钱
164         public override void Withdraw(double amount)
165         {
166             Balance -= amount;
167             StateChangeCheck();
168         }
169         public override void PayInterest()
170         {
171             Balance += Interest * Balance;
172             StateChangeCheck();
173         }
174
175         private void StateChangeCheck()
176         {
177             if (Balance < 0.0)
178             {
179                 Account.State = new RedState(this);
180             }
181             else if (Balance < LowerLimit)
182             {
183                 Account.State = new SilverState(this);
184             }
185         }
186     }
187
188     class App
189     {
190         static void Main(string[] args)
191         {
192             // 开一个新的账户
193             Account account = new Account("Learning Hard");
194
195             // 进行交易
196             // 存钱
197             account.Deposit(1000.0);
198             account.Deposit(200.0);
199             account.Deposit(600.0);
200
201             // 付利息
202             account.PayInterest();
203
204             // 取钱
205             account.Withdraw(2000.00);
206             account.Withdraw(500.00);
207
208             // 等待用户输入
209             Console.ReadKey();
210         }
211     }
212 }

  上面代码的运行结果如下图所示:

  从上图可以发现,进行存取款交易,会影响到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     }

四、状态者模式的应用场景

  在以下情况下可以考虑使用状态者模式。

  • 当一个对象状态转换的条件表达式过于复杂时可以使用状态者模式。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。
  • 当一个对象行为取决于它的状态,并且它需要在运行时刻根据状态改变它的行为时,就可以考虑使用状态者模式。

五、状态者模式的优缺点

  状态者模式的主要优点是:

  • 将状态判断逻辑每个状态类里面,可以简化判断的逻辑。
  • 当有新的状态出现时,可以通过添加新的状态类来进行扩展,扩展性好。

  状态者模式的主要缺点是:

  • 如果状态过多的话,会导致有非常多的状态类,加大了开销。

六、总结

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

时间: 2024-09-30 11:12:56

状态者模式的相关文章

C#设计模式(19)——状态者模式(State Pattern)

一.引言 在上一篇文章介绍到可以使用状态者模式和观察者模式来解决中介者模式存在的问题,在本文中将首先通过一个银行账户的例子来解释状态者模式,通过这个例子使大家可以对状态者模式有一个清楚的认识,接着,再使用状态者模式来解决上一篇文章中提出的问题. 二.状态者模式的介绍 每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时,那么就会对应很多的行为.那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码.这样的设

19.设计模式_状态者模式

一.引言 在上一篇文章介绍到可以使用状态者模式和观察者模式来解决中介者模式存在的问题,在本文中将首先通过一个银行账户的例子来解释状态者模式,通过这个例子使大家可以对状态者模式有一个清楚的认识,接着,再使用状态者模式来解决上一篇文章中提出的问题. 二.状态者模式的介绍 每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时,那么就会对应很多的行为.那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码.这样的设

C#设计模式-状态者模式

一. 状态者(State)模式 每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时,那么就会对应很多的行为.那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码.这样的设计显然违背了开闭原则.状态模式正是用来解决这样的问题的.状态模式将每种状态对应的行为抽象出来成为单独新的对象,这样状态的变化不再依赖于对象内部的行为. 状态模式——允许一个对象在其内部状态改变时自动改变其行为,对象看起来就像是改变了它的

19.状态者模式(State Pattern)

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { //每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时, //那么就会对应很多的行为.那么对这些状态的判断和根据状态完成的行为,就会导致多重

状态机模式

现在需要你做一个简单是视频播放器的APP,主要有播放,暂停,停止三个功能,在没学状态机模式之前,你可能会这样来实现: 现抽象个IPlayer接口,定义好你的播放器需要实现的动作和可能的状态字段: 01.1 public interface IPlayer { 02.2     public static final int STATE_PLAYING = 1; 03.3     public static final int STATE_PAUSED = 2; 04.4     public s

js状态模式

状态模式,当一个对象的内在状态改变时允许改变其行为,这个对象看起来是改变了其类. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化. 既然状态者模式是对已有对象的状态进行抽象,则自然就有抽象状态者类和具体状态者类,而原来已有对象需要保存抽象状态者类的引用,通过调用抽象状态者的行为来改变已有对象的行为.经过上面的分析,状态者模式的结构图也就很容易理解了,具体结构图如下图示. 从上图可知,状态者模式涉及

设计模式DesignPattern(六)行为型模式(下)

状态模式 每个对象都有其对应的状态,而每个状态又对应一些相应的行为,如果某个对象有多个状态时,那么就会对应很多的行为.那么对这些状态的判断和根据状态完成的行为,就会导致多重条件语句,并且如果添加一种新的状态时,需要更改之前现有的代码.这样的设计显然违背了开闭原则,状态模式正是用来解决这样的问题的. 状态模式——允许一个对象在其内部状态改变时自动改变其行为,对象看起来就像是改变了它的类.具体的结构图如下所示: 示例代码 就以银行账户的状态来实现下状态者模式.银行账户根据余额可分为RedState.

设计开篇

1 设计模式   类是我们面向对象编程的承载工具,可以说是面向对象的起点.  设计模式,这种算面向对象的进化.按照gof设计模式的分类  设计模式分为:创建型,结构型,行为型.  其中创建型主要和类的创建有关  结构性组织扩展类和类之间的关系  行为型主要扩展的类的访问  这三个对应到类上  创建型模式对应的是构造函数  结构型对应的是类的属性  行为型对应类的方法  就想我们以前学数学中很多证明题,都源自最基本的定理,面向对象编程也有类似的地方  设计模式就是类最基本功能的一个进化 2.依赖注

C#设计模式(0)-认识设计模式

简介 世界上本没有路,走的人多了也就成了路:世界上本来没有设计模式.用的人多了,也就成了设计模式.所以,我们不是严格按照它的定义去执行,可以根据自己的实际场景.需求去变通.领悟了其中的思想,实现属于自己的设计模式.通过对设计模式理解,让它它慢慢地影响你写代码的思维方式: 我们为什么要使用设计模式?使用设计模式是为了可重用代码,让代码容易被他人理解.保证代码可靠性以及可维护性. 最近看了一些关于设计模式的文章,以前也实际用过一些,这里希望将设计模式系列做一下总结,帮助我更深入地理解设计模式: 设计