zoukankan      html  css  js  c++  java
  • 设计模式——状态模式

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

    适用性

    • 一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为
    • 一个操作中含有庞大的多分支的的条件语句,且这些分支依赖于对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的的条件结构。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     }

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

  • 相关阅读:
    各大型邮箱smtp服务器及端口收集
    阿里云邮箱POP3、SMTP设置教程
    thinkphp使用PHPMailer发送邮件
    SMTP错误码建议解决方法
    又来杭州了
    外企
    陈志武竞然是date的独立董事
    今天在当当上买了几本书,内有51反利的优惠券,也是一个suprise,
    工作 心态
    中国互联网创业,最好的城市是哪里?
  • 原文地址:https://www.cnblogs.com/cwmizlp/p/9154222.html
Copyright © 2011-2022 走看看