同一个对象,内部属性不同的时候,具备的状态也不同
例子为银行的存款,默认申请的都是银卡,如果金额小于0并且在银行可容忍的状态内的话,为红色状态,如果数量很大,那么为金卡状态,否则为超大金额(这里暂时不论这个,其实都是一样的,只不过多加一个类而已)
红卡每次取钱需要服务费(这个也没什么用)
(各个状态之间通过属性限制,可以自由的进行切换,原理就是在内部进行各自的判别,达到一定数量的时候,切换到需要的实例上去)(通过账户类默认一个实例进入到状态列表中,自动实现各个状态动态切换选择)
多个状态切换的时候, 应用每个状态的内部状态类,完成类字段属性的传递!
//抽象状态类 abstract class State { protected Account account; protected double balance;//总金额 public double Balance { get { return balance; } set { balance = value; } } public Account Account { get { return account; } set{ account = value; } } protected double interest;//利率 protected double lowerLimit;//最小限制 protected double upperLimit;//最大限制 public abstract void Deposit(double amount);//存钱 public abstract void Withdraw(double amount);//取钱 public abstract void PayInterest();//支付利息 }
#region 具体状态类别 //红色状态卡 class RedState : State { double serviceFee;//服务费 public RedState(State state) { this.account = state.Account; this.Balance = state.Balance; Initialize(); } public void Initialize()//默认 { // Should come from a datasource interest = 0.0; lowerLimit = -100.0; upperLimit = 0.0; serviceFee = 15.00; } public override void Deposit(double amount) { Balance += amount; StateChangeCheck(); } public override void PayInterest() { //红卡表示在可容忍的情况下,欠费,无利息 } public override void Withdraw(double amount) { amount = amount - serviceFee; Console.WriteLine("No funds available for withdrawal!"); } private void StateChangeCheck() { if (Balance > upperLimit) { account.State = new SilverState(this); } } } //银卡 class SilverState :State { public SilverState(State state):this(state.Balance,state.Account) { } public SilverState(double balance, Account account) { this.balance = balance; this.account = account; Initialize(); } private void Initialize() { // Should come from a datasource interest = 0.0; lowerLimit = 0.0; upperLimit = 1000.0; } public override void Deposit(double amount) { balance += amount; StateChangeCheck(); } public override void PayInterest() { balance += interest*balance; StateChangeCheck(); } public override void Withdraw(double amount) { balance -= amount; StateChangeCheck(); } private void StateChangeCheck() { if (Balance > upperLimit) { account.State = new GoldState(this); } else if(Balance<lowerLimit) { account.State = new RedState(this); } } } //金卡 class GoldState : State { public GoldState(State state):this(state.Balance, state.Account) { } public GoldState(double balance, Account account) { this.balance = balance; this.account = account; Initialize(); } private void Initialize() { // Should come from a database interest = 0.05; lowerLimit = 1000.0; upperLimit = 10000000.0; } public override void Deposit(double amount) { balance += amount; StateChangeCheck(); } public override void PayInterest() { balance += interest * balance; StateChangeCheck(); } public override void Withdraw(double amount) { balance -= amount; StateChangeCheck(); } private void StateChangeCheck() { if (Balance > upperLimit) { Console.WriteLine("金额太大了,需要开会讨论一下了"); } else { account.State = new SilverState(this); } } } #endregion
// 账户类 class Account { public State State { get; set; } private string owner; public double Balance { get {return State.Balance; } } public Account(string name) { this.owner = name; State = new SilverState(0.0, this);//默认就是银卡 } public void Deposit(double amount) { State.Deposit(amount); Console.WriteLine("Deposited {0:C} --- ", amount); Console.WriteLine(" Balance = {0:C}", this.Balance); Console.WriteLine(" Status = {0} ", this.State.GetType().Name); Console.WriteLine(""); } public void Withdraw(double amount) { State.Withdraw(amount); Console.WriteLine("Withdrew {0:C} --- ", amount); Console.WriteLine(" Balance = {0:C}", this.Balance); Console.WriteLine(" Status = {0} ", this.State.GetType().Name); } public void PayInterest() { State.PayInterest(); Console.WriteLine("Interest Paid --- "); Console.WriteLine(" Balance = {0:C}", this.Balance); Console.WriteLine(" Status = {0} ", this.State.GetType().Name); } }
//实现 static void Main(string[] args) { // Open a new account Account account = new Account("Jim Johnson"); // Apply financial transactions account.Deposit(500.0); account.Deposit(300.0); account.Deposit(550.0); account.PayInterest(); account.Withdraw(2000.00); account.Withdraw(1100.00); // Wait for user Console.Read(); }
状态模式让对象最终知道它属于哪个状态,策略模式让对象找到属于自己的本身情况对应类别该执行的方法。