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

一箫攀、浩言

人靜而后安,安而能后定幼衰,定而能后慧靴跛,慧而能后悟,悟而能后得渡嚣。


二梢睛、背景

開年,看了看最近網(wǎng)上傳的《阿里巴巴Java開發(fā)規(guī)范》,然后看到了如下一部分识椰。

Paste_Image.png

這里說如果if else if else超過了三層就需要使用狀態(tài)設(shè)計模式扬绪。碰巧年前我寫了一個訂單狀態(tài)轉(zhuǎn)換的代碼,我沒有使用if else if else的形式裤唠,我使用了case,如果改為if等 就是if else if else形式了毅整。

code.png

所以我就在思考他嚷,這段代碼是否可以改為所說的狀態(tài)設(shè)計模式了?


三、狀態(tài)設(shè)計模式

3.1狀態(tài)模式定義:
狀態(tài)模式是屬于行為模式的范疇渗钉,即是對象在內(nèi)部狀態(tài)改變時改變它的行為航瞭,對象看起來好像修改了它的類诫硕。
下圖是截取《Head First 設(shè)計模式》中的圖片

Paste_Image.png

所以我上圖code.png圖片中,是沒有對象狀態(tài)變化或者行為的操作的刊侯。所以多層的if else if else也是要根據(jù)實(shí)際的代碼問題來做處理章办。下面上《Head First 設(shè)計模式》中的代碼如下
3.2 code代碼案例
State狀態(tài)類

package com.mouse.design.state;
/**
 * Created by wuhao on 2017/2/7.
 */
public interface State {

    public void insertQuarter();

    public void ejectQuarter();

    public void turnCrank();

    public void dispense();
}
package com.mouse.design.state;
/**
 * Created by wuhao on 2017/2/7.
 */
public class GumballMachine {
    State hasQuarterState;
    State noQuarterState;
    State soldOutState;
    State soldState;
    State winnerState;
    State state = soldOutState;
    int count = 0;
    public GumballMachine(int numberCount) {
        this.count = numberCount;
        hasQuarterState = new HasQuarterState(this);
        noQuarterState = new NoQuarterState(this);
        soldOutState = new SoldOutState(this);
        soldState = new SoldState(this);
        winnerState = new WinnerState(this);
        if (numberCount > 0) {
            state = noQuarterState;
        }
    }
    /**
     * 投幣
     */
    public void insertQuarter() {
        state.insertQuarter();
    }
    /**
     * 退還硬幣
     */
    public void ejectQuarter() {
        state.ejectQuarter();
    }
    /**
     * 轉(zhuǎn)動轉(zhuǎn)軸
     */
    public void turnCrank() {
        state.turnCrank();
        state.dispense();
    }
    void setState(State state) {
        this.state = state;
    }
    /**
     * 釋放糖果并且糖果數(shù)減1;
     */
    void releaseBall() {
        System.out.println("a gumball comes rolling  out the slot");
        if (count != 0) {
            count = count - 1;
        }
    }
    public State getHasQuarterState() {
        return hasQuarterState;
    }
    public void setHasQuarterState(State hasQuarterState) {
        this.hasQuarterState = hasQuarterState;
    }
    public State getNoQuarterState() {
        return noQuarterState;
    }
    public void setNoQuarterState(State noQuarterState) {
        this.noQuarterState = noQuarterState;
    }
    public State getSoldOutState() {
        return soldOutState;
    }
    public void setSoldOutState(State soldOutState) {
        this.soldOutState = soldOutState;
    }
    public State getSoldState() {
        return soldState;
    }
    public void setSoldState(State soldState) {
        this.soldState = soldState;
    }
    public State getWinnerState() {
        return winnerState;
    }
    public void setWinnerState(State winnerState) {
        this.winnerState = winnerState;
    }
    public State getState() {
        return state;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
}

HasQuarterState類

package com.mouse.design.state;
import java.util.Random;
/**
 * Created by wuhao on 2017/2/7.
 */
public class HasQuarterState implements State {

    GumballMachine gumballMachine;

    public HasQuarterState(GumballMachine gumballMachine) {
        this.gumballMachine = gumballMachine;
    }

    @Override
    public void insertQuarter() {
        System.out.println("你不能重復(fù)投幣");
    }

    @Override
    public void ejectQuarter() {
        System.out.println("退還投入的硬幣!1醭埂藕届!");
        gumballMachine.setState(gumballMachine.getNoQuarterState());
    }

    @Override
    public void turnCrank() {
        System.out.println("you turn...");
        int win = new Random().nextInt(10);
        System.out.println("win--->"+win);
        if( (0 == win) && gumballMachine.getCount() > 0  ){
            gumballMachine.setState(gumballMachine.getWinnerState());
        }else{
            gumballMachine.setState(gumballMachine.getSoldState());
        }
    }
    @Override
    public void dispense() {
        System.out.println("No gumball dispensed...");
    }
}

client.java類

package com.mouse.design.state;
/**
 * Created by wuhao on 2017/2/7.
 */
public class Client {
    public static void main(String[] args) {
        GumballMachine  gumballMachine = new GumballMachine(5);
        System.out.println("---------1--------");
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println("--------2-----");
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println("------3-------");
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println("------4-------");
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println("------5-------");
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();

        System.out.println("------6-------");
        gumballMachine.insertQuarter();
        gumballMachine.turnCrank();
    }
}

3.3 代碼
代碼已經(jīng)上傳到github上了,之前一直用bitbucket亭饵,不過現(xiàn)在把一些代碼弄到github上休偶。
https://github.com/MahoneWu/mouse-java-git.git

四:思考

最近看那個規(guī)范,覺得對于我來說還是有很大很大幫助的辜羊,其中的一些東西注意項(xiàng)踏兜,有說到需要注意的設(shè)計模式,比如"模板設(shè)計模式"八秃,這篇寫的"狀態(tài)設(shè)計模式"碱妆,其實(shí)設(shè)計模式在思維上是很特別的,寫法也是昔驱。所以狀態(tài)設(shè)計模式一般用于"狀態(tài)的變化并且業(yè)務(wù)復(fù)雜的"疹尾。
近期了把去年沒寫完的幾篇文章陸續(xù)發(fā)了,還有很早寫的兩篇比較簡單的設(shè)計模式的文章舍悯。都是簡單的記載下了航棱。并且所有的測試代碼都會放到github上面了。

五:浩語

                                           __                                                        
                            __  _  ____ __|  |__ _____    ___
                            \ \/ \/ /  |  \  |  \\__  \  /  _ \   
                             \     /|  |  /   Y  \/ __ \(  <_> )
                              \/\_/ |____/|___|  (____  /\____/ 
                                                    \/     \/          
                                 任何事情都是要靠努力和用心萌衬。                                                   
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饮醇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子秕豫,更是在濱河造成了極大的恐慌朴艰,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件混移,死亡現(xiàn)場離奇詭異祠墅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)歌径,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門毁嗦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人回铛,你說我怎么就攤上這事狗准】寺啵” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵腔长,是天一觀的道長袭祟。 經(jīng)常有香客問我,道長捞附,這世上最難降的妖魔是什么巾乳? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮鸟召,結(jié)果婚禮上胆绊,老公的妹妹穿的比我還像新娘。我一直安慰自己药版,他們只是感情好辑舷,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著槽片,像睡著了一般何缓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上还栓,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天碌廓,我揣著相機(jī)與錄音,去河邊找鬼剩盒。 笑死谷婆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辽聊。 我是一名探鬼主播纪挎,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼跟匆!你這毒婦竟也來了异袄?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤玛臂,失蹤者是張志新(化名)和其女友劉穎烤蜕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體迹冤,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讽营,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了泡徙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片橱鹏。...
    茶點(diǎn)故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚀瘸,到底是詐尸還是另有隱情狡蝶,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布贮勃,位于F島的核電站,受9級特大地震影響苏章,放射性物質(zhì)發(fā)生泄漏寂嘉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一枫绅、第九天 我趴在偏房一處隱蔽的房頂上張望泉孩。 院中可真熱鬧,春花似錦并淋、人聲如沸寓搬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽句喷。三九已至,卻和暖如春兔毙,著一層夾襖步出監(jiān)牢的瞬間唾琼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工澎剥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锡溯,地道東北人。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓哑姚,卻偏偏與公主長得像祭饭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子叙量,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評論 2 361

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,330評論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理倡蝙,服務(wù)發(fā)現(xiàn),斷路器宛乃,智...
    卡卡羅2017閱讀 134,716評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法悠咱,類相關(guān)的語法,內(nèi)部類的語法征炼,繼承相關(guān)的語法析既,異常的語法,線程的語...
    子非魚_t_閱讀 31,665評論 18 399
  • 認(rèn)輸入軸: Horizontal 和 Vertical被映射到w, a, s, d鍵和方向鍵Fire1, Fire...
    _涼笙閱讀 832評論 0 0
  • 天下沒有不散的宴席谆奥,兩個月的實(shí)習(xí)結(jié)束了眼坏,鐵警學(xué)子終將直面離別。交警的實(shí)習(xí)經(jīng)歷,盡管辛苦宰译,卻也甘甜:有路面執(zhí)勤的肉體...
    mzyin閱讀 417評論 0 1