標籤:java 設計模式
當一個類A的某個成員變數的值變化時,可能導致多個行為表現得不同。將該成員變數封裝成類型的模式,即為狀態模式(state pattern)。
編程技巧:以多態來重構分支結構。
設計思路:解決狀態添加、狀態轉換、狀態對行為的影響問題。
狀態決定行為
先不考慮狀態轉換,很容易看到狀態決定行為的情境。“朋友來了有好酒,若是那豺狼來了,迎接它的有獵槍”。不在狀態,該贏的比賽都會輸。
常式 4-3 又見分支結構package property.state;public class Man{ private boolean isHappy;//典型的flag,兩種狀態 public String sayHello() { String greeting=""; if(isHappy){ greeting ="你好,我的朋友"; }else{ greeting ="好"; } return greeting; } public String sayGoodbye() { return isHappy? "再抱抱!":"再見,再也不見"; } public static void main(String[] args) {Man one = new Man();one.isHappy =true;//falseSystem.out.println(one.sayHello());System.out.println(one.sayGoodbye());}}這種Man沒有城府,當成員變數isHappy取值不同時,Man的sayHello()和sayGoodbye()等多個行為表現得不同。
在簡單情境中,if-else更簡潔。
然而,世界不是黑白分明的,關鍵成員變數可以是int或枚舉類型表示的好感度,或某個類型如顧客(土豪、凡人、釣絲)。隨著狀態取值可能性的添加,分支塊越來越大,sayHello()和sayGoodbye()代碼都變得龐大。特別是增加新的狀態值,在分支結構下違反OCP。
所以,從編程技巧上看,狀態模式和策略模式、Factory 方法模式一樣,以多態來重構分支結構。
重構的要點:①以狀態類State替代boolean、int、枚舉類型或類型(注意這種情況)的分支判斷參數,顯然有多少分支,State將對應有多少子類。②狀態類State將所有具有上述分支判斷的方法,提取為自己的介面,State的子類分別給出
配套的實現。
常式 4-4 State的子類們package property.state;public interface State{ public String sayHello(); public String sayGoodbye();}package property.state;public class FriendState implements State{ @Override public String sayHello(){ return "你好,我的朋友"; } @Override public String sayGoodbye(){ return "再抱抱!"; }}//OpposingState略package property.state;public class Man2{ private State state; public String sayHello() { return state.sayHello(); } public String sayGoodbye() { return state.sayGoodbye(); } public static void main(String[] args) {Man2 one = new Man2();one.state =new FriendState();//isHappy = trueSystem.out.println(one.sayHello());System.out.println(one.sayGoodbye());}}
在不考慮狀態轉換時,單純從代碼上看,狀態模式的State封裝多個方法,而策略模式僅封裝一個方法。此時,
狀態模式與策略模式的關係,如同抽象工廠與Factory 方法的關係。
雖然狀態模式封裝多個方法,與抽象工廠一樣,不會出現[3.2.4方法類型化]的常式3-5那樣的組合爆炸,因為多個方法在一個狀態下是配套的,而非任意的組合。
yqj2065在設計模式學習難度係數排名中,狀態模式給的難度係數高達5分(10分制)。如果僅僅是策略模式基礎上的一變多,難度係數應該是1.
在Man的代碼中是通過設定isHappy的值改變其狀態,在Man2中是通過設定State的物件類型改變其狀態。狀態之間的變換由外界控制,或者說,多種狀態是分割的、無關的。這種情況下,學習狀態模式的難度係數最多是1。
但是,狀態模式最有趣的地方正是其狀態的變遷。將涉及一個比較高端的術語Finite State Machine 有限狀態機器。
2.狀態的變遷
.....
簡明 狀態模式(5.8)