隨筆 - 12, 文章 - 0, 評論 - 5, 引用 - 0
          數(shù)據(jù)加載中……

          設(shè)計模式--狀態(tài)模式(State)

          前幾天由于忙工作上的事情,每天加班到10點(diǎn)左右才回家,回到家就沒有再開電腦更新東西,今天早了一些回家,開始繼續(xù)更新東西,今天要寫的是狀態(tài)模式,哦,對于一個沒有狀態(tài)的人來說,寫狀態(tài)模式,不知道會寫成什么樣子,反正是一起討論用嘛,能把我所知道的清楚表達(dá)出來已經(jīng)很心滿意足啦。在理解狀態(tài)模式的時候,我總覺得它和策略模式很像很像,有人說它們是孿生兄弟,那我們現(xiàn)在看看狀態(tài)模式到底是一個什么樣的東西。

          狀態(tài)模式是對象的一個行為模式,它允許一個對象在其內(nèi)部狀態(tài)改變的時候改變其行為,這個對象看上去就像改了了它的類一樣。

          下圖是關(guān)于紅綠燈轉(zhuǎn)換的一個實(shí)現(xiàn)類圖,具體的轉(zhuǎn)換是這樣子的,在初始的情況下,設(shè)定一個燈的狀態(tài),比如是綠燈,那么燈的下一個狀態(tài)則是黃燈,緊接著是紅燈,然后再是綠燈,依次循環(huán);通過改變燈的狀態(tài),改變其行為。

          下面是這個類圖的實(shí)現(xiàn)代碼:

          package com.plabmedia.state;

          public interface LightState {

          /**
          * 打印當(dāng)前的狀態(tài)
          */
          public void print(Light light);

          }

          package com.plabmedia.state;

          public class RedLight implements LightState{

          @Override
          public void print(Light light) {
          System.out.println("current state is red");
          light.setState(new GreenLight());
          }

          }

          package com.plabmedia.state;

          public class YellowLight implements LightState{

          @Override
          public void print(Light light) {
          System.out.println("current state is yellow");
          light.setState(new RedLight());
          }

          }

          package com.plabmedia.state;

          public class GreenLight implements LightState {

          @Override
          public void print(Light light) {
          System.out.println("current state is green");
          light.setState(new YellowLight());
          }

          }

          package com.plabmedia.state;

          public class Light {

          private LightState state;

          public LightState getState() {
          return state;
          }

          public void setState(LightState state) {
          this.state = state;
          }

          public void print(){
          state.print(this);
          }

          public Light(LightState state){
          this.state = state;
          }

          }

          package com.plabmedia.state;

          public class Client {

          public static void main(String args[]){
          Light light = new Light(new GreenLight());
          light.print();
          light.print();
          light.print();
          light.print();
          light.print();
          light.print();
          }

          }

          運(yùn)行結(jié)果:

          current state is green
          current state is yellow
          current state is red
          current state is green
          current state is yellow
          current state is red

          上面是對狀態(tài)模式一個小小的實(shí)現(xiàn),這個實(shí)現(xiàn)也僅僅是認(rèn)識級的,在我們實(shí)際應(yīng)用中,如果用到狀態(tài)模式,應(yīng)該比這個要負(fù)責(zé)的多,只是基本的結(jié)構(gòu)是相似的。那我們下面針對狀態(tài)模式做一些討論。

          1.在什么情況下使用狀態(tài)模式:

          • 一個對象的行為依賴于它所處的狀態(tài),對象的行為必須隨著其狀態(tài)的改變而改變;
          • 需要多多重條件轉(zhuǎn)移語句進(jìn)行演化的時候,可以把每個分支封裝成一個狀態(tài)類;現(xiàn)在寫代碼的時候,我是不太喜歡用條件轉(zhuǎn)移語句,特別是最好的那個else語句,我覺得它承擔(dān)的東西太多了,前面不滿足的情況它都要來處理,憑什么啊。
          2.狀態(tài)模式要注意的地方:
          • 誰來定義狀態(tài)的變化:客戶端還是狀態(tài)內(nèi)部決定?這要看當(dāng)時應(yīng)用的環(huán)境,如果狀態(tài)的變化是固定的,我覺得可以再客戶端進(jìn)行設(shè)定;如果狀態(tài)的變化依賴于前一個狀態(tài),比如在工作流系統(tǒng)中,當(dāng)前狀態(tài)是依賴于前一個狀態(tài)的,這需要狀態(tài)內(nèi)部來覺得。
          • 狀態(tài)對象創(chuàng)建時機(jī):需要的時候創(chuàng)建?還是事先創(chuàng)建好所有的對象,供需要的時候調(diào)用?這要分系統(tǒng)需要來決定,如果一個系統(tǒng),狀態(tài)變化的順序固定,不那么頻繁,則可以在需要的時候創(chuàng)建所需要的對象;否則,對于頻繁變化的狀態(tài),從性能上將,還是首先創(chuàng)建好各個狀態(tài)對象,供需要時調(diào)用。
          • 可以把環(huán)境類傳到具體的狀態(tài)類中,狀態(tài)類在需要的時候調(diào)用環(huán)境類,比如示例中的樣子,其實(shí)在每個狀態(tài)類里面,也可以直接調(diào)用環(huán)境類的print方法,這樣看來,Client只需要初始化環(huán)境類,然后就可以看到它的狀態(tài)在不停地變化。
          3.狀態(tài)模式與策略模式的區(qū)別:
          我粗俗的說一些,從我的理解的基礎(chǔ)上,二者之間的區(qū)別在于狀態(tài)模式在集體作戰(zhàn),而策略模式是單兵作戰(zhàn),怎么說呢?狀態(tài)模式因為其內(nèi)部狀態(tài)的改變會有不同的行為出現(xiàn),而對于策略模式,只要客戶端選中了一種策略,在整個生命周期內(nèi),都是這種策略。所以,在區(qū)分使用狀態(tài)模式和策略模式的時候,主要是看系統(tǒng)有沒有狀態(tài)的變化,如果系統(tǒng)在整個生命周期內(nèi),只有一種狀態(tài),那很好,選擇策略模式;如果系統(tǒng)在整個過程中,狀態(tài)多樣性,那需要選擇狀態(tài)模式。
          先寫這么多吧,好沒有狀態(tài)啊,希望大家都抽出時間一起討論,說說自己對狀態(tài)模式的看法。

          posted on 2012-07-21 22:23 拼搏 閱讀(1040) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 二连浩特市| 新郑市| 和田县| 达拉特旗| 偏关县| 介休市| 静宁县| 唐河县| 盘锦市| 波密县| 台中县| 高邮市| 惠来县| 玛纳斯县| 昌平区| 大安市| 常州市| 竹山县| 依安县| 伊金霍洛旗| 七台河市| 巴彦淖尔市| 黔东| 阜新市| 德格县| 丰城市| 安西县| 胶州市| 庄浪县| 岑溪市| 望江县| 宁陕县| 漳州市| 永川市| 喀喇| 宿迁市| 孝昌县| 松潘县| 洛浦县| 迁西县| 彰化县|