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


介紹

  • 狀態(tài)模式的行為是由狀態(tài)來決定的,不同狀態(tài)下有不同的行為尿招。

  • 狀態(tài)模式和策略模式的結(jié)構(gòu)幾乎完全一樣矾柜,但是他們的目的,本質(zhì)卻完全不一樣:

    • 區(qū)別: 狀態(tài)模式的行為是平行的就谜,不可替換的怪蔑,策略模式的行為是彼此獨(dú)立,可以相互替換的

    • 描述:狀態(tài)模式把對(duì)象的行為包裝在不同的狀態(tài)對(duì)象里丧荐,每一個(gè)狀態(tài)對(duì)象都有一個(gè)共同的抽象狀態(tài)積累缆瓣。狀態(tài)模式的意圖是讓每一個(gè)對(duì)象在其內(nèi)部 狀態(tài)改變的時(shí)候,行為也隨之改變

定義

當(dāng)一個(gè)對(duì)象內(nèi)的轉(zhuǎn)改改變時(shí)虹统,允許改變其行為弓坞,這個(gè)對(duì)象看起來像是改變了其類

使用場(chǎng)景

  • 一個(gè)對(duì)象的行為取決于他的狀態(tài),并且他必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變他的行為
  • 代碼中大量與狀態(tài)有關(guān)的語句窟却,例如:一個(gè)操作中含有龐大的分支語句昼丑,且這些分支依賴于該對(duì)象的狀態(tài)
  • 狀態(tài)模式將每一個(gè)條件分支放入一個(gè)獨(dú)立的類中,這使得你可以根據(jù)對(duì)象自身的情況將對(duì)象的狀態(tài)作為一個(gè)對(duì)象夸赫,這一對(duì)象可以不依賴其他對(duì)象而獨(dú)立變化菩帝,這樣通過多態(tài)來去除過多的,重復(fù)的 if-else 分支語句

UML圖解 (待補(bǔ)充)


代碼示例

  • 普通實(shí)現(xiàn)
  public class TvController {

    private static int BASE_STATE = 0;
    private final static int POWER_OFF = BASE_STATE + 1;
    private final static int POWER_ON = BASE_STATE + 2;
    private int mState = POWER_OFF;

    public void powerOn() {
        mState = POWER_ON;
        if (mState == POWER_OFF) {
            System.out.println("開機(jī)");
        }
    }

    public void powerOff() {
        mState = POWER_OFF;
        if (mState == POWER_ON) {
            System.out.println("關(guān)機(jī)");
        }
    }

    public void nextChannel() {
        if (mState == POWER_ON) {
            System.out.println("下一個(gè)頻道");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

    public void prevChannel() {
        if (mState == POWER_ON) {
            System.out.println("上一個(gè)頻道");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

    public void turnOn() {
        if (mState == POWER_ON) {
            System.out.println("調(diào)高音量");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

    public void turnDown() {
        if (mState == POWER_ON) {
            System.out.println("調(diào)低音量");
        } else {
            System.out.println("error tv is powerOff !!");
        }
    }

}

可以看到茬腿,在TVController類中呼奢,通過mState來存儲(chǔ)電視的狀態(tài),并且在各個(gè)操作中都需要通過if-else來判斷狀態(tài)切平,代碼重復(fù)握础,相對(duì)較為混亂

  • 狀態(tài)模式實(shí)現(xiàn)

使用狀態(tài)模式:將這些狀態(tài)用對(duì)象來代替,將這些行為封裝到對(duì)象中悴品,是的不同的狀態(tài)下有不同的實(shí)現(xiàn)禀综,這樣就將這些if-else 從TVController類
去掉简烘,整個(gè)代碼也看起來清晰起來。

  • TvState.java : 抽象類 實(shí)現(xiàn)Tv相關(guān)操作
  public interface TvState {
    public void nextChannel();
    public void prevChannel();
    public void turnUp();
    public void turnDown();
}
  • PowerOffState.java :關(guān)機(jī)狀態(tài)實(shí)現(xiàn)類
  public class PowerOfferState implements TvState {

    @Override
    public void nextChannel() {
    }

    @Override
    public void prevChannel() {
    }

    @Override
    public void turnOn() {
    }

    @Override
    public void turnDown() {
    }
}
  • PowerOnState.java :開機(jī)狀態(tài)實(shí)現(xiàn)類
  public class PowerOnState implements TvState {

    @Override
    public void nextChannel() {
        print("下一頻道");
    }

    @Override
    public void    prevChannel() {
        print("上一頻道");
    }

    @Override
    public void turnOn() {
        print("調(diào)高音量");
    }

    @Override
    public void turnDown() {
        print("調(diào)低音量");
    }

    private void print(String msg) {
        System.out.println(msg);
    }
    
}
  • PowerController.java : 開關(guān)機(jī)控制抽象類
  public interface PowerController {

    public TvState mState;
    public void setState(TvState state);
    public void powerOn();    
    public void powerOff();
}
  • TvControllerImp.java
  public class TvControllerImp implements PowerController {

    @Override
    public void setState(TvState state) {
        mState = state;
    }

    @Override
    public void powerOn() {
        setState(new PowerOnState());

        System.out.println("開機(jī)");
    }

    @Override
    public void powerOff() {
        setState(new PowerOffState());

        System.out.println("關(guān)機(jī)");
    }

    public void nextChannel() {
        mState.nextChannel();
    }

    public void prevChannel() {
        mState.prevChannel();
    }

    public void turnOn() {
        mState.turnOn();
    }

    public void turnDown() {
        mState.turnDown();
    }
}
  • 測(cè)試代碼
  public class TvClient {
    public static void main(String[] args) {
        TvControllerImp tv = new TvControllerImp();
        // 開機(jī)
        tv.powerOn();
        // 下一個(gè)頻道
        tv.nextChannel();
        // 調(diào)高音量
        tv.turnOn();
        // 調(diào)低音量
        tv.turnDown();
        // 關(guān)機(jī)
        tv.powerOff();
        // 調(diào)高音量定枷,電視不響應(yīng)
        tv.turnOn();
    }
}
  • Android中的應(yīng)用實(shí)例--WiFi管理
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末孤澎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子欠窒,更是在濱河造成了極大的恐慌覆旭,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岖妄,死亡現(xiàn)場(chǎng)離奇詭異型将,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)荐虐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門七兜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缚俏,你說我怎么就攤上這事惊搏≈椋” “怎么了忧换?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)向拆。 經(jīng)常有香客問我亚茬,道長(zhǎng),這世上最難降的妖魔是什么浓恳? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任刹缝,我火速辦了婚禮,結(jié)果婚禮上颈将,老公的妹妹穿的比我還像新娘梢夯。我一直安慰自己,他們只是感情好晴圾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布颂砸。 她就那樣靜靜地躺著,像睡著了一般死姚。 火紅的嫁衣襯著肌膚如雪人乓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天都毒,我揣著相機(jī)與錄音色罚,去河邊找鬼。 笑死账劲,一個(gè)胖子當(dāng)著我的面吹牛戳护,可吹牛的內(nèi)容都是我干的金抡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼腌且,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼竟终!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起切蟋,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤统捶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后柄粹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喘鸟,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年驻右,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了什黑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堪夭,死狀恐怖愕把,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情森爽,我是刑警寧澤恨豁,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站爬迟,受9級(jí)特大地震影響橘蜜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜付呕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一计福、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧徽职,春花似錦象颖、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至育韩,卻和暖如春克蚂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背筋讨。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工埃叭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悉罕。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓赤屋,卻偏偏與公主長(zhǎng)得像立镶,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子类早,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容