C# 设计模式-状态模式
一.介绍
状态模式(State Pattern)。属于行为型模式。当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
二.实现
举个例子,用银行账户的状态来实现状态模式,状态分为两种,一种是正常有钱可以取的状态,一种是已经透支了不能再取钱的状态。每次存钱取钱都会刷新一下这个账户的状态。
public class Account { public State State { get; set; } public string Owner { get; set; } public Account(string owner) { this.Owner = owner; this.State = new NormalState(0.0, this); } public double Balance { get { return State.Balance; } } // 余额 // 存钱 public void Deposit(double amount) { State.Deposit(amount); Console.WriteLine("存款金额为 {0:C}——", amount); Console.WriteLine("账户余额为 =:{0:C}", this.Balance); Console.WriteLine("账户状态为: {0}", this.State.GetType().Name); Console.WriteLine(); } // 取钱 public void Withdraw(double amount) { State.Withdraw(amount); Console.WriteLine("取款金额为 {0:C}——", amount); Console.WriteLine("账户余额为 =:{0:C}", this.Balance); Console.WriteLine("账户状态为: {0}", this.State.GetType().Name); Console.WriteLine(); } } // 抽象状态类 public abstract class State { // Properties public Account Account { get; set; } public double Balance { get; set; } // 余额 public double LowerLimit { get; set; } // 下限 public double UpperLimit { get; set; } // 上限 public abstract void Deposit(double amount); // 存款 public abstract void Withdraw(double amount); // 取钱 } // Red State意味着Account透支了 public class RedState : State { public RedState(State state) { // Initialize this.Balance = state.Balance; this.Account = state.Account; LowerLimit = -100.00; UpperLimit = 0.00; } // 存款 public override void Deposit(double amount) { Balance += amount; StateChangeCheck(); } // 取钱 public override void Withdraw(double amount) { Console.WriteLine("没有钱可以取了!"); } private void StateChangeCheck() { if (Balance > UpperLimit) { Account.State = new NormalState(this); } } } // Normal State正常状态 public class NormalState : State { public NormalState(State state) : this(state.Balance, state.Account) { } public NormalState(double balance, Account account) { this.Balance = balance; this.Account = account; LowerLimit = 0.00; UpperLimit = 1000.00; } public override void Deposit(double amount) { Balance += amount; StateChangeCheck(); } public override void Withdraw(double amount) { Balance -= amount; StateChangeCheck(); } private void StateChangeCheck() { if (Balance < LowerLimit) { Account.State = new RedState(this); } } } //调用 public static void Main(string[] args) { // 开一个新的账户 var account = new Account("Learning Hard"); // 进行交易 // 存钱 account.Deposit(1000.0); account.Deposit(200.0); account.Deposit(600.0); // 取钱 account.Withdraw(2000.00); account.Withdraw(500.00); }
Account类内部存储着State的状态,State的抽象类定义了改变状态所需要执行的方法,具体状态类则是实现抽象类的方法,根据情况重新改变Account的状态。
三.总结
优点
1.将状态判断的逻辑放在每一个状态类里,可以简化判断的逻辑。
2.当有新的状态出现时,可以通过增加新的状态类来拓展,拓展性好。
缺点:
1.如果状态类过多的话,会导致有非常多的状态类,加大了开销。