Unity【話大】設計模式之狀態模式
前言:筆者在最開始寫程式的時候經常會遇到一種情況,例如更改一個欄位、或者新增一種小功能,就要把原來寫過的東西幾乎廢棄掉,或者更改大量以前寫過的程式碼。又或者自己寫的東西時間久了再去回顧,完全找不到到時為什麼這麼寫的頭緒,如果遇到了Bug更是無法快速定位在哪裡小範圍出現的問題。如果你也經常遇到這種問題,就說明你現階段非常需要學習下設計模式了。
在網上經常說的設計模式有23種,也有一些更多的設計模式,無非也是從這些設計模式中變種而來。如果讓筆者來形容什麼是設計模式,我認為設計模式是:一種思想,一種模式,一種套路,一種解決問題的高效策略。
有說的不正確或者不準確的地方歡迎留言指正
有什麼有趣的寫作技巧或者想法歡迎大家給我留言,大家的幫助是我寫下去最有效的動力
今天筆者跟大家介紹一個新的設計模式----狀態模式,下面以有A、B、C三個狀態進行分別跳轉,跳轉順序A--->B--->C,且這3個狀態會有自己行為方式,就以這個示例展示狀態模式如何使用
狀態模式(State) 當一個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。
初始程式碼
public class Context
{
public string state;
public void Change()
{
if (state =="A")
{
this.Log("執行A先關操作");
}
else if (state =="B")
{
this.Log("執行B先關操作");
}
else if (state == "C")
{
this.Log("執行C先關操作");
}
}
}
呼叫
void Start()
{
Context context = new Context();
context.state = "A";
context.Change();
context.state = "B";
context.Change();
context.state = "C";
context.Change();
}
對應列印日誌
老套路,我們開始進行抽象 封裝和轉移
首先我們把其中的if else判斷中的行為進行封裝,轉移到不同的state中自行管理
public abstract class State
{
public abstract void Handle();
}
public class StateA : State
{
public override void Handle()
{
this.Log("執行A先關操作1");
this.Log("執行A先關操作2");
this.Log("執行A先關操作3");
}
}
public class StateB : State
{
public override void Handle()
{
this.Log("執行B先關操作1");
this.Log("執行B先關操作2");
this.Log("執行B先關操作3");
}
}
public class StateC : State
{
public override void Handle()
{
this.Log("執行C先關操作1");
this.Log("執行C先關操作2");
this.Log("執行C先關操作3");
}
}
對應Context中的更改
public class Context
{
public State state;
public void SetState(State state)
{
this.state = state;
}
public void Change()
{
if (state is StateA)
{
state.Handle();
}
else if (state is StateB)
{
state.Handle();
}
else if (state is StateC)
{
state.Handle();
}
}
}
呼叫就變成了這個樣子
void Start()
{
Context context = new Context();
context.state = new StateA();
context.Change();
context.state = new StateB();
context.Change();
context.state = new StateC();
context.Change();
}
因為是他是按順序的跳轉機制,我們再次改造 ,把相關的跳轉封裝到各自的state中去
State
public abstract class State
{
public abstract void Handle();
public abstract void Change(Context context);
}
public class StateA : State
{
public override void Handle()
{
this.Log("執行-- A --先關操作1");
}
public override void Change(Context context)
{
Handle();
context.state = new StateB();
}
}
public class StateB : State
{
public override void Handle()
{
this.Log("執行-- B --先關操作1");
}
public override void Change(Context context)
{
Handle();
context.state = new StateC();
}
}
public class StateC : State
{
public override void Handle()
{
this.Log("執行-- C --先關操作1");
}
public override void Change(Context context)
{
Handle();
context.state = new StateA();
}
}
Contenxt
public class Context
{
public State state;
public Context(State state)
{
this.state = state;
}
public void Change()
{
state.Change(this);
}
}
呼叫
void Start()
{
Context context = new Context(new StateA());
context.Change(); //執行A並跳轉B狀態
context.Change(); //執行B並跳轉C狀態
context.Change(); //執行C並跳轉A狀態
context.Change(); //執行A並跳轉B狀態
context.Change(); //執行B並跳轉C狀態
context.Change(); //執行C並跳轉A狀態
}
以上就是狀態模式的最終版。狀態模式主要解決的是當控制一個物件狀態裝換的條件表示式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。
所以當一個物件的行為取決於它的狀態,並且他必須在執行時刻根據狀態改變它的行為時,就可以考慮使用狀態模式。
狀態模式好處與用處
狀態模式的好處是將與特定狀態相關的行為區域性化,並且將不同狀態的行為分割開來
將特定的狀態相關的行為都放入一個物件中,由於所有與狀態相關的程式碼都存在於某個ConcreteState中,所以通過定義新的子類可以很容易地增加新的裝填和轉換。
狀態模式通過把各種狀態轉移邏輯分佈到State的子類之間,來減少相互間的依賴
優點:
1、封裝了轉換規則,也就是將與特定狀態相關的行為區域性化,並且將不同狀態的行為分割開來
2、列舉可能的狀態,在列舉狀態之前需要確定狀態種類。
3、將所有與某個狀態有關的行為放到一個類中,並且可以方便地增加新的狀態只需要改變物件狀態即可改變物件的行為。
4、允許狀態轉換邏輯與狀態物件合成一體,而不是某一個巨大的條件語句塊。
5、可以讓多個環境物件共享一個狀態物件,從而減少系統中物件的個數。
缺點:
1、狀態模式的使用必然會增加系統類和物件的個數。
2、狀態模式的結構與實現都較為複雜,如果使用不當將導致程式結構和程式碼的混亂。
3、狀態模式對"開閉原則"的支援並不太好,對於可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的原始碼,否則無法切換到新增狀態,而且修改某個狀態類的行為也需修改對應類的原始碼。
相關文章
- 設計模式之——狀態模式設計模式
- PHP 設計模式之狀態模式PHP設計模式
- 設計模式20之狀態模式設計模式
- 設計模式之狀態模式(State)設計模式
- C#設計模式之狀態模式C#設計模式
- 設計模式漫談之狀態模式設計模式
- 設計模式:狀態模式設計模式
- 設計模式-狀態模式設計模式
- 無廢話設計模式(14)結構型模式--狀態模式設計模式
- 折騰Java設計模式之狀態模式Java設計模式
- python設計模式狀態模式Python設計模式
- 設計模式(十五)狀態模式設計模式
- 設計模式之策略模式和狀態模式(strategy pattern & state pattern)設計模式
- 設計模式(二十一)----行為型模式之狀態模式設計模式
- 設計模式-狀態模式(State Pattern)設計模式
- 《Head First 設計模式》:狀態模式設計模式
- 簡說設計模式——狀態模式設計模式
- 極簡設計模式-狀態模式設計模式
- GoLang設計模式14 - 狀態模式Golang設計模式
- python設計模式【9】-狀態模式Python設計模式
- 設計模式之狀態模式(三分鐘學會一個設計模式)設計模式
- 23種設計模式(七)-狀態設計模式設計模式
- 大話設計模式設計模式
- 設計模式第八講-狀態模式設計模式
- 設計模式--直譯器模式和狀態模式設計模式
- 【設計模式】設計模式(一)-- 大話設計模式讀書筆記設計模式筆記
- Java進階篇設計模式之十二 ---- 備忘錄模式和狀態模式Java設計模式
- 用設計模式去掉沒必要的狀態變數 —— 狀態模式設計模式變數
- 行為型設計模式 - 狀態模式詳解設計模式
- 《設計模式七》備忘錄、模板方法、狀態模式及設計模式設計總結設計模式
- 設計模式大冒險第五關:狀態模式,if/else的“終結者”設計模式
- 《JavaScript設計模式與開發實踐》模式篇(13)—— 狀態模式JavaScript設計模式
- 23種設計模式之——動態代理模式設計模式
- 大話 PHP 設計模式--建立型PHP設計模式
- 軟體設計模式系列之二十二——狀態模式設計模式
- 軟體設計模式學習(二十四)狀態模式設計模式
- 大話設計模式:今天你設計了嗎?設計模式
- 23種設計模式之代理模式(靜態代理)設計模式