狀态模式(State Pattern),當一個對象的内在狀态改變時允許改變其行為,這個對象看起來像是改變了其類。
狀态模式主要解決的是當控制一個對象狀态裝換的條件表達式過于複雜時的情況。把狀态的判斷邏輯轉移到表示不同狀态的一系列類中,可以把複雜的判斷邏輯簡單化。
當一個對象行為取決于它的狀态,并且它必須在運作時刻根據狀态改變它的行為時,就可以考慮使用狀态模式了。

Context類:維護一個ConcreteState子類的一個執行個體,這個執行個體定義目前的狀态。
State類:抽象狀态類,定義一個接口以封裝與Context的一個特定狀态相關的行為。
ConcreteStateA,ConcreteStateB,ConcreteStateC類:具體狀态類,每一個子類實作一個與Context的一個狀态相關的行為。
1、Context類:維護一個ConcreteState子類的一個執行個體,這個執行個體定義目前的狀态
public class Context
{
private State state;
public StateState
{
get { return state; }
set
{
state = value;
Console.WriteLine("目前狀态是:" + state.GetType().Name);
}
}
public Context(State state)
this.state = state;
Console.WriteLine("初始狀态是:"+state.GetType().Name);
public void Request()
state.Handle(this);
}
2、抽象狀态類及其具體實作類
public abstract class State
public abstract void Handle(Context context);
public class ConcreteStateA:State
public override void Handle(Context context)
context.State = new ConcreteStateB();
public class ConcreteStateB: State
context.State = new ConcreteStateC();
public class ConcreteStateC : State
context.State = new ConcreteStateA();
4、用戶端代碼
static void Main(string[] args)
Context context = new Context(new ConcreteStateA());
context.Request();
Console.Read();
銀行賬戶根據餘額可分為三種狀态RedState,SilverState,GoldState,這些狀态分别代表了透支帳戶(overdrawn accounts),新開帳戶(starter accounts),标準帳戶(accounts in good standing)..如下圖所示
RedState類:賬号餘額在範圍【0.0,1000.0】表示處于處于SilverState。否則轉換為其他狀态。
if (balance < lowerLimit)
account.State = new RedState(this);
else if (balance > upperLimit)
account.State = new GoldState(this);
SilverState類:賬号餘額在範圍【-100.0,0】表示處于處于RedState。否則轉換為其他狀态。
if (balance > upperLimit)
account.State = new SilverState(this);
GoldState類:賬号餘額在範圍【1000.0,10000000.0】表示處于處于GoldState。否則轉換為其他狀态。
if (balance < 0.0)
else if (balance < lowerLimit)
1、類Account,相當于Context類
class Account
private State _state;
private string _owner;
// Constructor
public Account(string owner)
// New accounts are 'Silver' by default
this._owner = owner;
this._state = new SilverState(0.0, this);
// Properties
public double Balance
get { return _state.Balance; }
public StateState
get { return _state; }
set { _state = value; }
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(" Status = {0}\n",
public void PayInterest()
_state.PayInterest();
Console.WriteLine("Interest Paid --- ");
Console.WriteLine(" Status = {0}\n",
2、抽象狀态類State及其具體狀态類RedState,SilverState,GoldState
/// <summary>
/// The 'State' abstract class
/// </summary>
abstract class State
protected Account account;
protected double balance;
protected double interest;
protected double lowerLimit;
protected double upperLimit;
public Account Account
get { return account; }
set { account = value; }
get { return balance; }
set { balance = value; }
public abstract void Deposit(double amount);
public abstract void Withdraw(double amount);
public abstract void PayInterest();
/// <summary>
/// A 'ConcreteState' class
/// <remarks>
/// Red indicates that account is overdrawn
/// </remarks>
class RedState : State
private double _serviceFee;
// Constructor
public RedState(State state)
this.balance = state.Balance;
this.account = state.Account;
Initialize();
private 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 Withdraw(double amount)
amount = amount - _serviceFee;
Console.WriteLine("No funds available for withdrawal!");
public override void PayInterest()
// No interest is paid
private void StateChangeCheck()
if (balance > upperLimit)
{
account.State = new SilverState(this);
}
/// Silver indicates a non-interest bearing state
class SilverState : State
// Overloaded constructors
public SilverState(State state)
:
this(state.Balance, state.Account)
public SilverState(double balance, Account account)
this.balance = balance;
this.account = account;
lowerLimit = 0.0;
upperLimit = 1000.0;
public override void Withdraw(double amount)
balance -= amount;
balance += interest * balance;
if (balance < lowerLimit)
account.State = new RedState(this);
else if (balance > upperLimit)
account.State = new GoldState(this);
/// Gold indicates an interest bearing state
class GoldState : State
public GoldState(State state)
: this(state.Balance, state.Account)
public GoldState(double balance, Account account)
// Should come from a database
interest = 0.05;
lowerLimit = 1000.0;
upperLimit = 10000000.0;
{
if (balance < 0.0)
else if (balance < lowerLimit)
3、用戶端代碼
// 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.ReadKey();
狀态模式(State Pattern),當一個對象的内在狀态改變時允許改變其行為,這個對象看起來像是改變了其類。當一個對象行為取決于它的狀态,并且它必須在運作時刻根據狀态改變它的行為時,就可以考慮使用狀态模式了。
版權
作者:靈動生活 郝憲玮
如果你認為此文章有用,請點選底端的【推薦】讓其他人也了解此文章,
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。