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

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

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

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

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

          下面是這個(gè)類圖的實(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

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

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

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

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


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 常熟市| 武宁县| 高安市| 静安区| 赤城县| 拉孜县| 巨野县| 大厂| 招远市| 平舆县| 商水县| 陕西省| 新巴尔虎左旗| 资溪县| 台安县| 达尔| 汉源县| 合山市| 齐河县| 开化县| 任丘市| 年辖:市辖区| 云龙县| 博白县| 黎川县| 墨竹工卡县| 罗江县| 仙居县| 百色市| 宜兰县| 葫芦岛市| 南丹县| 元江| 武川县| 宜章县| 泸水县| 甘孜县| 汕尾市| 洪雅县| 夹江县| 南雄市|