<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

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

    一、State模式定義:

    不同的狀態(tài),不同的行為;或者說,每個狀態(tài)有著相應的行為.

    二、State模式的適用場合:

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

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

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

    四、“開關切換狀態(tài)” 和“ 一般的狀態(tài)判斷”區(qū)別:

    “開關狀態(tài)切換”經(jīng)常發(fā)生在GUI界面的交互過程中,通過結(jié)合對象當前狀態(tài)和參數(shù),判斷接下來對象應該切換到什么狀態(tài)。被判斷對象和被更新對象都是同一個。這一點和“一般的狀態(tài)判斷”是不同的,后者是根據(jù)其它對象或?qū)傩缘闹祦砀伦陨淼臓顟B(tài)。被判斷對象和被更新對象不是同一個。

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

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

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

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

    五、State模式的構(gòu)成:

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

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

    六、State模式的例子:

    狀態(tài)機--父類定義

    public abstract class State// 狀態(tài)行為的父類

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

    }

    狀態(tài)機--子類實現(xiàn)
    public class BlueState extends State{

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

      }


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


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

    }

    特點:

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


    狀態(tài)機管理器
    public class Context{

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

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


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


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

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

      }


    }

    特點:

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

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


    七、狀態(tài)機模式的優(yōu)點:

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

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

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

    十、狀態(tài)模式和其它模式的結(jié)合應用:

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



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


    FeedBack:
    # re: 設計模式總結(jié)-State模式
    2011-11-28 10:45 | joyjjjz
    很好,謝謝!  回復  更多評論
      
    # re: 設計模式總結(jié)-State模式[未登錄]
    2012-08-28 22:11 | james
    good  回復  更多評論
      
    <2012年8月>
    2930311234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿(21)

    隨筆分類

    隨筆檔案

    BlogJava熱點博客

    好友博客

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 搡女人免费免费视频观看| 亚洲精品在线电影| 国产亚洲综合一区二区三区| 亚洲网站在线免费观看| 亚洲综合日韩中文字幕v在线| 久久国产乱子伦精品免费午夜| 亚洲精品成人在线| xxxx日本在线播放免费不卡| JLZZJLZZ亚洲乱熟无码| 一级特黄录像免费播放中文版| 青青青国产色视频在线观看国产亚洲欧洲国产综合 | 99免费精品视频| 国产亚洲av片在线观看16女人| 免费国产污网站在线观看| 亚洲VA中文字幕不卡无码| 亚欧日韩毛片在线看免费网站| 91大神亚洲影视在线| 成人免费毛片内射美女-百度| 亚洲日韩国产欧美一区二区三区| 在线免费观看毛片网站| 亚洲码和欧洲码一码二码三码| 又大又粗又爽a级毛片免费看| 免费夜色污私人影院网站| 亚洲欧洲日本在线| 久久黄色免费网站| 亚洲精品综合一二三区在线| 7x7x7x免费在线观看| 亚洲风情亚Aⅴ在线发布| 亚洲 自拍 另类小说综合图区| 久久不见久久见免费影院www日本| 亚洲视频精品在线| 免费特级黄毛片在线成人观看| a级毛片免费观看在线| 久久夜色精品国产亚洲AV动态图| 日韩版码免费福利视频| 日韩免费码中文在线观看| 亚洲AV色香蕉一区二区| 暖暖免费高清日本中文| 国产免费爽爽视频在线观看| 学生妹亚洲一区二区| 国产AV无码专区亚洲AV漫画|