posts - 262,  comments - 221,  trackbacks - 0
          注:本文多處引用了WWW.jdon.com網站的《State模式》一文,原文前參見:http://www.jdon.com/designpatterns/designpattern_State.htm

          一、State模式定義:

          不同的狀態,不同的行為;或者說,每個狀態有著相應的行為.

          二、State模式的適用場合:

          State模式在實際使用中比較多,適合"狀態的切換".因為我們經常會使用If elseif else 進行狀態切換, 如果針對狀態的這樣判斷切換反復出現,我們就要聯想到是否可以采取State模式了.

          三、State模式與Command模式的比較:

          前者從調用者和被調用者的角度出發,目的是封裝被調用者的行為,讓調用者只和統一的頂層接口打交道。后者從對象自身的狀態出發,不涉及調用者和被調用者。是對象自身的狀態切換導致的行為變化。

          四、“開關切換狀態” 和“ 一般的狀態判斷”區別:

          “開關狀態切換”經常發生在GUI界面的交互過程中,通過結合對象當前狀態和參數,判斷接下來對象應該切換到什么狀態。被判斷對象和被更新對象都是同一個。這一點和“一般的狀態判斷”是不同的,后者是根據其它對象或屬性的值來更新自身的狀態。被判斷對象和被更新對象不是同一個。

          例如:if (which==1) state="hello";
             else if (which==2) state="hi";
             else if (which==3) state="bye";

          這是一個 " 一般的狀態判斷",state值的不同是根據which變量來決定的,which和state沒有關系.如果改成:

          if (state.euqals("bye")) state="hello";
          else if (state.euqals("hello")) state="hi";
          else if (state.euqals("hi")) state="bye";

          這就是 "開關切換狀態",是將state的狀態從"hello"切換到"hi",再切換到""bye";再切換到"hello",好象一個旋轉開關,這種狀態改變就可以使用State模式了.

          五、State模式的構成:

          1.state manager 狀態管理器,就是開關,如上面例子的Context實際就是一個state manager, 在state manager中有對狀態的切換動作.

          2.用抽象類或接口實現的父類,,不同狀態就是繼承這個父類的不同子類(也就是不同的狀態行為)

          六、State模式的例子:

          狀態機--父類定義

          public abstract class State// 狀態行為的父類

                
          // 狀態機需要能夠感知上下文的情況,也就是之前的狀態和目前的情形,所以用Context作為參數
               public abstract void handlepush(Context c);
            public abstract void handlepull(Context c);
            public abstract void getcolor();

          }

          狀態機--子類實現
          public class BlueState extends State{

            
          public void handlepush(Context c){
               
          //根據push方法"如果是blue狀態的切換到green" ;
               c.setState(new GreenState());

            }


            
          public void handlepull(Context c){
                      
          //根據pull方法"如果是blue狀態的切換到red" ;
              c.setState(new RedState());
                }


            
          public abstract void getcolor()return (Color.blue)}

          }

          特點:

          ·擁有一個父類,表示各種不同的狀態。該父類具有三個典型的方法:
              ·切換到上一個狀態
              ·切換到下一個狀態
              ·獲取當前狀態
          ·擁有一至多個子類,在子類中實現具體的狀態向前、向后的切換
          ·如果把每個狀態看成一個“狀態鏈”上的一個獨立的節點,那么有N個狀態,則需要N個子類。
          ·如果狀態只支持單向切換,則除了首尾兩個狀態,其它狀態的節點均有兩個方法,分別是向前/后一個狀態的切換
          ·如果狀態支持雙向切換(例如MP3的自動循環播放功能),則尾節點可以有兩個狀態切換的方法


          狀態機管理器
          public class Context{

            
          private Sate state=null; //我們將原來的 Color state 改成了新建的State state;

            
          //setState是用來改變state的狀態 使用setState實現狀態的切換,不同的狀態傳入不同的State,都是State的子類
            pulic void setState(State state){
              
          this.state=state;
                }


            
          public void push(){
                      
          //狀態的切換的細節部分,在本例中是顏色的變化,已經封裝在子類的handlepush中實現,這里無需關心
              state.handlepush(this);
              
              
          //因為sample要使用state中的一個切換結果,使用getColor()
              Sample sample=new Sample(state.getColor());
              sample.operate(); 
                }


            
          public void pull(){
                    state.handlepull(this);

              Sample2 sample2
          =new Sample2(state.getColor());
              sample2.operate(); 

            }


          }

          特點:

          ·擁有一個狀態機對象:用于代表當前的狀態
          ·擁有一個切換到上/下一個狀態的方法:實際上是調用了狀態機自身的切換方法,由于狀態機本身已經“知道”自己是什么狀態,所以可以方便的切換到上、下一個狀態。例如:state.handlePush(this)這個方法,由于此時state對象是什么類型已經知道(通過對管理器中的狀態機賦值),所以切換工作就交給了對象本身了,調用者不需要知道內部是如何切換的。
          ·擁有一個獲取當前狀態的方法

          我們可以看到,在狀態機的上下文中,push和pull方法都把上下文本身作為參數傳遞給狀態機,然后在狀態機中調用了上下文的setState(Context c)方法。這是一個典型的Call-back(回調)機制。


          七、狀態機模式的優點:

          (1) 封裝轉換過程,也就是轉換規則
          (2) 枚舉可能的狀態,因此,需要事先確定狀態種類。

          使用狀態模式后,客戶端外界可以直接使用事件Event實現,根本不必關心該事件導致如何狀態變化,這些是由狀態機等內部實現。這是一種Event-condition-State,狀態模式封裝了condition-State部分。

          每個狀態形成一個子類,每個狀態只關心它的下一個可能狀態,從而無形中形成了狀態轉換的規則。如果新的狀態加入,只涉及它的前一個狀態修改和定義。

          十、狀態模式和其它模式的結合應用:

          從狀態模式的實質:“只關心它的下一個可能狀態”和客戶端使用特點:“使用事件Event實現”來看,我們可以考慮將觀察者模式(Observer)和狀態模式(State)結合起來。被觀察者在改變時發送廣播消息(Event事件),觀察著注意并接收該消息后,使用狀態機來對當前應用的上下文進行狀態的切換。



          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2008-04-07 18:02 Paul Lin 閱讀(7621) 評論(2)  編輯  收藏 所屬分類: 模式與重構


          FeedBack:
          # re: 設計模式總結-State模式
          2011-11-28 10:45 | joyjjjz
          很好,謝謝!  回復  更多評論
            
          # re: 設計模式總結-State模式[未登錄]
          2012-08-28 22:11 | james
          good  回復  更多評論
            
          <2008年4月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 通江县| 新河县| 久治县| 普兰店市| 闸北区| 中宁县| 濮阳市| 阳原县| 察隅县| 扎鲁特旗| 巫溪县| 中卫市| 富裕县| 扎赉特旗| 克什克腾旗| 孝义市| 朝阳区| 涿州市| 南华县| 望谟县| 岱山县| 昔阳县| 罗江县| 聊城市| 湟源县| 上饶市| 武安市| 沁阳市| 苗栗县| 阳山县| 民丰县| 西平县| 淳化县| 大城县| 中牟县| 正安县| 体育| 平遥县| 苍山县| 普定县| 昭通市|