設計模式(二十一)—— 狀態模式
阿新 • • 發佈:2018-07-16
uml public bubuko interface 對象 con 原理 處理 環境
模式簡介
允許一個對象在其內部狀態改變時改變它的行為。對象看起來似乎修改了它的類。
在某些情況下,一個對象的行為取決於它當前所處的狀態,當對象屬性(狀態)在系統運行過程中發生變化,它呈現出的行為也隨之發生改變。例如可調節亮度的臺燈,假設燈光亮度分為三級,每次按下按鈕,臺燈會根據當前亮度增加一級,若已經是最亮的狀態,按下按鈕則關閉臺燈。
結構分析
UML類圖
角色說明
- Context
環境類。客戶端操作的類,包含一個IState類型的對象,保存其當前狀態。
- IState
狀態接口。定義一個統一的接口以封裝與Context的特定狀態相關的行為。
- ConcreteState
具體狀態。實現狀態接口,表示Context某個狀態相關的行為。
工作原理
Context類將與狀態相關的請求委托給ConcreteState對象處理,並將自身以參數形式傳遞給ConcreteState對象,如此,便可以在處理完請求後訪問Context的SetState方法為Context設置新的狀態。
結構代碼
//環境類 class Context { private IState _state; public Context(IState state) { _state = state; Console.WriteLine($"Initialize state -> {state}"); } public void SetState(IState state) { _state = state; Console.WriteLine($"Set State -> {state}"); } public void Request() { _state.Handle(this); } } //狀態接口 interface IState { void Handle(Context context); } //具體狀態類A class ConcreteStateA : IState { public void Handle(Context context) { context.SetState(new ConcreteStateB()); } } //具體狀態類B class ConcreteStateB : IState { public void Handle(Context context) { context.SetState(new ConcreteStateA()); } } //客戶端調用 static void Main(string[] args) { Context context = new Context(new ConcreteStateA()); for (int i = 0; i < 5; i++) { context.Request(); } Console.ReadLine(); }
程序輸出:
示例分析
本節模擬第一節中提到的臺燈示例。首先創建臺燈類Lamp,提供共有方法SetState設置當前狀態,包含一個保存當前狀態的私有字段_state,並通過Request方法調用該狀態的下臺燈發光的行為。
class Lamp { private IState _state; public Lamp(IState state) { _state = state; Console.WriteLine($"Initialize state -> {state}"); } public void SetState(IState state) { _state = state; Console.WriteLine($"Set State -> {state}"); } public void Request() { _state.Handle(this); } }
聲明狀態接口,並分別實現具體狀態類,這裏包括四種狀態Closed、Dim、Medium、Bright。
interface IState
{
void Handle(Lamp context);
}
class Closed : IState
{
public void Handle(Lamp context)
{
context.SetState(new Dim());
}
}
class Dim : IState
{
public void Handle(Lamp context)
{
context.SetState(new Medium());
}
}
class Medium : IState
{
public void Handle(Lamp context)
{
context.SetState(new Bright());
}
}
class Bright : IState
{
public void Handle(Lamp context)
{
context.SetState(new Closed());
}
}
客戶端調用,將臺燈的初始狀態設置為Closed,並連續調用,輸出臺燈狀態。
class Program
{
static void Main(string[] args)
{
Lamp lamp = new Lamp(new Closed());
for (int i = 0; i < 10; i++)
{
lamp.Request();
}
Console.ReadLine();
}
}
程序輸出:
適用場景
一個對象的行為取決於它的狀態,並且它必須在運行時刻根據狀態改變它的行為。
一個操作中含有大量的分支的條件語句,且這些分支依賴於該對象的狀態。
設計模式(二十一)—— 狀態模式