簡明 狀態模式(5.8)

來源:互聯網
上載者:User

標籤: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)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.