設(shè)計(jì)模式---StateMode

一、什么是StateMode(狀態(tài)模式)

???狀態(tài)模式與上一篇寫(xiě)的設(shè)計(jì)模式---Strategy模式》具體實(shí)現(xiàn)結(jié)構(gòu)有點(diǎn)相似豁生,兩者之間都是通過(guò)注入不同的子對(duì)象得到不同的操作行為耻瑟,但是兩者的實(shí)現(xiàn)目的完全不同蛉幸。例如革半,狀態(tài)模式的行為是平行,我們可以直接通過(guò)注入不同的狀態(tài)子類對(duì)象從而獲得不同狀態(tài)的操作舶斧,并且狀態(tài)是可以切換的欣鳖。而策略模式察皇,則是通過(guò)注入不同的操作對(duì)象從而獲得不同的操作行為茴厉,不同的注入方式直接,他們的行為是獨(dú)立的什荣。下面做一個(gè)區(qū)分:

(一)區(qū)別:
???狀態(tài)模式將各個(gè)狀態(tài)所對(duì)應(yīng)的操作分離開(kāi)來(lái)矾缓,即對(duì)于不同的狀態(tài),通過(guò)注入狀態(tài)稻爬,由不同的子類實(shí)現(xiàn)具體操作嗜闻,不同狀態(tài)的切換由子類實(shí)現(xiàn),當(dāng)發(fā)現(xiàn)傳入?yún)?shù)不是自己這個(gè)狀態(tài)所對(duì)應(yīng)的參數(shù)桅锄,則自己給Context類切換狀態(tài)琉雳;而策略模式是直接依賴注入到Context類的參數(shù)進(jìn)行選擇策略,不存在切換狀態(tài)的操作友瘤。

(二)聯(lián)系:
???狀態(tài)模式和策略模式都是為具有多種可能情形設(shè)計(jì)的模式翠肘,把不同的處理情形抽象為一個(gè)相同的接口,符合對(duì)擴(kuò)展開(kāi)放辫秧,對(duì)修改封閉的原則束倍。

總而言之!兩者就像孿生兄弟C讼贰P髅谩!

二柿究、該模式適應(yīng)范圍

(一)針對(duì)同一類型問(wèn)題有多種處理方式邮旷,具體行為也有差別的時(shí)候
(二)需要安全地封裝多種同一類型的操作時(shí)
(三)出現(xiàn)同一抽象類有多個(gè)子類,有需要通過(guò)if..else..或switch..case選擇具體子類時(shí)

三蝇摸、具體應(yīng)用

???筆者對(duì)于這個(gè)模式比較有感觸婶肩,這里先用電視機(jī)根據(jù)關(guān)機(jī)與開(kāi)機(jī)兩者不同狀態(tài),遙控器有不同操作行為作為案例分析探入。其次在通過(guò)我們實(shí)戰(zhàn)中狡孔,對(duì)于現(xiàn)在有一些APP應(yīng)用,不一定強(qiáng)制性要求登錄才可以進(jìn)行某些操作蜂嗽,因此則出現(xiàn)登錄與非登錄狀態(tài)的時(shí)候會(huì)出現(xiàn)不同的狀態(tài)苗膝,所以自然我們可以使用----狀態(tài)模式!V簿伞辱揭!

一离唐、電視機(jī)應(yīng)用---狀態(tài)模式
1.首先定義電視機(jī)操作接口

package cn.wsy.mymode.stateMode;
 
/**
 * 電視機(jī)操作
 * Created by wsy on 2016/2/23.
 */
public interface TvStateControl {
 
    public void upVolume();
 
    public void downVolume();
 
    public void nextChannel();
 
    public void beforeChannel();
 
}

2.不同狀態(tài)之間的電視機(jī)操作(開(kāi)機(jī)、關(guān)機(jī))

package cn.wsy.mymode.stateMode;
 
import android.util.Log;
 
/**
 * Created by wsy on 2016/2/23.
 */
public class PowerOnState implements TvStateControl {
 
    private final String TAG = "PowerOnState";
 
    @Override
    public void upVolume() {
        Log.i(TAG,"音量提高中..,");
    }
 
    @Override
    public void downVolume() {
        Log.i(TAG,"音量降低中..,");
    }
 
    @Override
    public void nextChannel() {
        Log.i(TAG,"下一個(gè)頻道..,");
    }
 
    @Override
    public void beforeChannel() {
        Log.i(TAG,"上一個(gè)頻道..,");
    }
}
package cn.wsy.mymode.stateMode;
 
import android.util.Log;
 
/**
 * 關(guān)機(jī)的操作
 * Created by wsy on 2016/2/23.
 */
public class PowerOffState implements TvStateControl{
 
    private final String TAG = "PowerOffState";
 
    @Override
    public void upVolume() {
        Log.i(TAG,"關(guān)機(jī)咯");
    }
 
    @Override
    public void downVolume() {
        Log.i(TAG,"關(guān)機(jī)咯");
    }
 
    @Override
    public void nextChannel() {
        Log.i(TAG,"關(guān)機(jī)咯");
    }
 
    @Override
    public void beforeChannel() {
        Log.i(TAG,"關(guān)機(jī)咯");
    }
}

3.電視中遙控控制類

package cn.wsy.mymode.stateMode;
 
/**
 * 電視機(jī)控制類
 * Created by wsy on 2016/2/23.
 */
public class TvControl {
 
    TvStateControl stateControl;
 
    public TvControl(TvStateControl stateControl) {
        this.stateControl = stateControl;
    }
 
    /**
     * 這里作為切換狀態(tài)接口
     * @param stateControl
     */
    public void setStateControl(TvStateControl stateControl) {
        this.stateControl = stateControl;
    }
 
    public void upVolume() {
        stateControl.upVolume();
    }
 
    public void downVolume() {
        stateControl.downVolume();
    }
 
    public void nextChannel() {
        stateControl.nextChannel();
    }
 
    public void beforeChannel() {
        stateControl.beforeChannel();
    }
}

4.測(cè)試
???如果我們不采用模式設(shè)計(jì)程序问窃,一般我們?cè)O(shè)計(jì)思路會(huì)是if...else...硬編碼的判斷模式亥鬓,例如以下代碼:

    public void traditionalTest(int tvState) {
        //int tvState = 0;//0 開(kāi)機(jī) 1關(guān)機(jī)
        //調(diào)聲音
        upVolume(tvState);
        //調(diào)頻道
        nextChannel(tvState);
    }
 
 //傳統(tǒng)
    public void upVolume(int state) {
        if (state == 0) {
            Log.i(TAG, "音量提高中..,");
        }else{
            Log.i(TAG, "關(guān)機(jī)啦..,");
        }
    }
 
    public void downVolume(int state) {
        if (state == 0) {
            Log.i(TAG,"音量降低中..,");
        }else{
            Log.i(TAG, "關(guān)機(jī)啦..,");
        }
    }
 
    public void nextChannel(int state) {
        if (state == 0) {
            Log.i(TAG,"下一個(gè)頻道..,");
        }else{
            Log.i(TAG, "關(guān)機(jī)啦..,");
        }
    }
 
    public void beforeChannel(int state) {
        if (state == 0) {
            Log.i(TAG,"上一個(gè)頻道..,");
        }else{
            Log.i(TAG, "關(guān)機(jī)啦..,");
        }
    }

???這種方式,會(huì)增加更多if..else重復(fù)代碼域庇,可維護(hù)性也不高嵌戈,如果狀態(tài)增加,我們將要去每個(gè)涉及到狀態(tài)判斷的類文件去修改對(duì)應(yīng)邏輯听皿,這樣同樣違反了程序設(shè)計(jì)的封閉原則熟呛,不推薦!
???相反尉姨,利用狀態(tài)模式的實(shí)現(xiàn)代碼庵朝,如下:

   public void modeTest() {
        //注入狀態(tài)操作
        TvControl tvControl = new TvControl(new PowerOnState());
        //調(diào)聲音 開(kāi)機(jī)
        tvControl.upVolume();
        //關(guān)機(jī) 再操作
        tvControl.setStateControl(new PowerOffState());
        tvControl.nextChannel();
    }

結(jié)果:


???相反,這種模式不用硬生生利用if..else..等判斷語(yǔ)句去處理又厉,再切換狀態(tài)的時(shí)候九府,我們只需要通過(guò)注入新的狀態(tài)子對(duì)象,即可以獲取不同的操作方式覆致!如果需求增加狀態(tài)屬性侄旬,我們也不需要直接去修改判斷語(yǔ)句,只需要重新增加狀態(tài)子對(duì)象篷朵,再次注入即可9磁!声旺!大大增加程序維護(hù)性笔链!

二、實(shí)戰(zhàn)應(yīng)用(登錄與非登錄行為)---狀態(tài)模式

???APP部分功能腮猖。這樣鉴扫,便會(huì)出現(xiàn)登錄與非登錄兩種狀態(tài)會(huì)出現(xiàn)不同的行為,因此這里便可以聯(lián)想到這篇博客學(xué)習(xí)的----狀態(tài)模式3喝薄F捍础!下面舉出簡(jiǎn)單例子(這里約定要登錄才能進(jìn)入個(gè)人中心姐赡、進(jìn)行評(píng)論莱预,進(jìn)行轉(zhuǎn)發(fā),否則會(huì)自動(dòng)進(jìn)入登錄界面项滑。)
1.涉及到登錄的所有行為 接口

package cn.wsy.mymode.stateMode.modeForLogin;
 
/**
 * 涉及到登錄操作的行為動(dòng)作
 * Created by wsy on 2016/2/23.
 */
public interface LoginState {
 
    /**
     * 進(jìn)入個(gè)人中心
     */
    public void toPersonalCenter();
 
    /**
     * 進(jìn)行評(píng)論
     */
    public void commenting();
 
    /**
     * 進(jìn)行轉(zhuǎn)發(fā)
     */
    public void transpondMsg();
 
}

2.不同狀態(tài)的操作(登錄與非登錄)

package cn.wsy.mymode.stateMode.modeForLogin;
 
import android.util.Log;
 
/**
 * 已經(jīng)登錄
 * Created by wsy on 2016/2/23.
 */
public class LoginedState implements LoginState{
 
    private final String TAG =  "LoginedState";
 
    @Override
    public void toPersonalCenter() {
        Log.i(TAG,"進(jìn)入個(gè)人中心界面");
    }
 
    @Override
    public void commenting() {
        Log.i(TAG,"進(jìn)行評(píng)論");
    }
 
    @Override
    public void transpondMsg() {
        Log.i(TAG,"進(jìn)行轉(zhuǎn)發(fā)");
    }
 
}
package cn.wsy.mymode.stateMode.modeForLogin;
 
import android.util.Log;
 
/**
 * 登出操作
 * Created by wsy on 2016/2/23.
 */
public class LoginOutState implements LoginState{
 
    private final String TAG =  "LoginedState";
 
    @Override
    public void toPersonalCenter() {
        Log.i(TAG,"進(jìn)入個(gè)人中心失敗依沮,進(jìn)入登錄界面");
    }
 
    @Override
    public void commenting() {
        Log.i(TAG,"進(jìn)行評(píng)論失敗,進(jìn)入登錄界面");
    }
 
    @Override
    public void transpondMsg() {
        Log.i(TAG,"進(jìn)行轉(zhuǎn)發(fā)失敗,進(jìn)入登錄界面");
 

3.登錄狀態(tài)行為操作靜態(tài)控制類

/**
 * 登錄控制類
 * Created by wsy on 2016/2/23.
 */
public class LoginControl {
 
    LoginState loginedState;
 
    public LoginControl(LoginState loginedState) {
        this.loginedState = loginedState;
    }
 
    public void setLoginedState(LoginState loginedState) {
        this.loginedState = loginedState;
    }
 
    public void toPersonalCenter() {
        loginedState.toPersonalCenter();
    }
 
    public void commenting() {
        loginedState.commenting();
    }
 
    public void transpondMsg() {
        loginedState.transpondMsg();
    }
}

4.測(cè)試結(jié)果

 @Override
    public void modeTest() {
        LoginControl loginControl = new LoginControl(new LoginOutState());
        //默認(rèn)沒(méi)有登錄
        loginControl.toPersonalCenter();
        //登錄后 再操作
        loginControl.setLoginedState(new LoginedState());
        loginControl.toPersonalCenter();
    }

傻小孩b mark 共勉

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市危喉,隨后出現(xiàn)的幾起案子宋渔,更是在濱河造成了極大的恐慌,老刑警劉巖辜限,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件皇拣,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡薄嫡,警方通過(guò)查閱死者的電腦和手機(jī)氧急,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)岂座,“玉大人态蒂,你說(shuō)我怎么就攤上這事》咽玻” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵手素,是天一觀的道長(zhǎng)鸳址。 經(jīng)常有香客問(wèn)我,道長(zhǎng)泉懦,這世上最難降的妖魔是什么稿黍? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮崩哩,結(jié)果婚禮上巡球,老公的妹妹穿的比我還像新娘。我一直安慰自己邓嘹,他們只是感情好酣栈,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著汹押,像睡著了一般矿筝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棚贾,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天窖维,我揣著相機(jī)與錄音,去河邊找鬼妙痹。 笑死铸史,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的怯伊。 我是一名探鬼主播琳轿,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了利赋?” 一聲冷哼從身側(cè)響起水评,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎媚送,沒(méi)想到半個(gè)月后中燥,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡塘偎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年疗涉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吟秩。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咱扣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涵防,到底是詐尸還是另有隱情闹伪,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布壮池,位于F島的核電站偏瓤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏椰憋。R本人自食惡果不足惜厅克,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望橙依。 院中可真熱鬧证舟,春花似錦、人聲如沸窗骑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)慧域。三九已至鲤竹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昔榴,已是汗流浹背辛藻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留互订,地道東北人吱肌。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像仰禽,于是被迫代替她去往敵國(guó)和親氮墨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子纺蛆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,070評(píng)論 25 707
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)规揪,斷路器桥氏,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法猛铅,內(nèi)部類的語(yǔ)法字支,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法奸忽,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,622評(píng)論 18 399
  • 最近堕伪,一款短視頻應(yīng)用小咖秀突然爆紅,不僅王珞丹栗菜、華妃娘娘蔣欣等明星玩得不亦可乎欠雌,而其還沖上了AppStore免費(fèi)榜...
    夢(mèng)依雪原閱讀 310評(píng)論 0 0
  • 馬上三十了 身體真是一天不如一天 以前洗完頭出去跑一點(diǎn)不適沒(méi)有 現(xiàn)在用吹風(fēng)機(jī)吹完了睡覺(jué),起來(lái)頭都快炸了 加上最近工...
    d7a855630997閱讀 157評(píng)論 0 0