設計模式之狀態(tài)模式(行為型)--- 21

  • 一、導語
  • 二、怎么用
    1.樣例背景
    2.UML類圖
    3.代碼示例
  • 三、優(yōu)缺點
  • 四、使用場景
    1.概括描述
    2.現(xiàn)存知名產(chǎn)品中的使用示例
  • 五、與其他設計模式的對比
  • 六、參考

一、導語

狀態(tài)模式(State),容許一個對象在其內(nèi)部狀態(tài)改變時,改變他的行為(當然不改變他的行為,只做狀態(tài)的轉換,也是可以的)。

一定長度上可以簡化 if/else 分支帶來的麻煩。

二、怎么用

共有2個示例,代碼詳見訪問鏈接
下面以example2舉例說明

1. 樣例背景

模擬程序員一天中不同狀態(tài)的切換
工作時通常有如下狀態(tài):
1.上午狀態(tài)
2.中午狀態(tài)
3.下午狀態(tài)
4.傍晚狀態(tài)
5.加班狀態(tài)
6.猝死狀態(tài)

(注:該代碼有執(zhí)行順序的要求,僅做示例)

2. UML類圖

WorkState ------------------- 狀態(tài)抽象類
XxxxState ---------------- 具體的狀態(tài)類
Work ----------------------------- 模擬具體的工作情況的類

example2 使用狀態(tài)模式后 UML類圖

3. 代碼示例

/**
 * description:  工作狀態(tài)抽象類
 */
public abstract class WorkState {
    abstract void programming(Work work);
}


/**
 * description:  上午狀態(tài)
 */
public class MorningState extends WorkState {
    @Override
    void programming(Work work) {
        if (work.getHour() < 12 && work.getHour() >= 9) {
            System.out.println(
                    String.format("當前時間為: %s,精神狀態(tài)很好,效率很高!—— 【 %s 】",
                            work.getHour(), work.getWorkState().getClass().getSimpleName()));
        }else { // 超過12點,轉入中午工作狀態(tài)
            work.setWorkState(new NoonState());
            work.programming();
        }
    }
}


/**
 * description:  中午工作狀態(tài)
 */
public class NoonState extends WorkState {
    @Override
    void programming(Work work) {
        if (work.getHour() < 14  && work.getHour() >= 12) {
            System.out.println(
                    String.format("當前時間為: %s,剛吃飽,有點困!—— 【 %s 】",
                            work.getHour(), work.getWorkState().getClass().getSimpleName()));
        }else { // 超過14點,轉入下午工作狀態(tài)
            work.setWorkState(new AfterNoonState());
            work.programming();
        }
    }
}


/**
 * description:  下午工作狀態(tài)
 */
public class AfterNoonState extends WorkState {
    @Override
    void programming(Work work) {
        if (work.getHour() < 17  && work.getHour() >= 14) {
            System.out.println(
                    String.format("當前時間為: %s,中午沒睡,有點疲倦,效率不高!—— 【 %s 】",
                            work.getHour(), work.getWorkState().getClass().getSimpleName()));
        }else { // 超過17點,轉入傍晚工作狀態(tài)
            work.setWorkState(new EveningState());
            work.programming();
        }
    }
}


/**
 * description:  傍晚工作狀態(tài)
 */
public class EveningState extends WorkState {
    @Override
    void programming(Work work) {
        if (work.getHour() < 19  && work.getHour() >= 17) {
            System.out.println(
                    String.format("當前時間為: %s,快到晚飯時間了,有點餓了!—— 【 %s 】",
                            work.getHour(), work.getWorkState().getClass().getSimpleName()));
        }else { // 超過19點,轉入加班工作狀態(tài)
            work.setWorkState(new WorkOvertimeState());
            work.programming();
        }
    }
}


/**
 * description:  加班工作狀態(tài)
 */
public class WorkOvertimeState extends WorkState {
    @Override
    void programming(Work work) {
        if (work.getHour() < 22 && work.getHour() >= 19) {
            System.out.println(
                    String.format("當前時間為: %s,領導不讓下班,非給找點活!—— 【 %s 】",
                            work.getHour(), work.getWorkState().getClass().getSimpleName()));
        }else { // 超過22點,轉入猝死工作狀態(tài)
            work.setWorkState(new SuddenDeathState());
            work.programming();
        }
    }
}


/**
 * description:  猝死工作狀態(tài)
 */
public class SuddenDeathState extends WorkState {
    @Override
    void programming(Work work) {
        if ((work.getHour() < 24  && work.getHour() >= 22)
                || (work.getHour() < 4  && work.getHour() >= 0)){
            System.out.println(
                    String.format("當前時間為: %s,要猝死了!—— 【 %s 】",
                            work.getHour(), work.getWorkState().getClass().getSimpleName()));
        }else { // 轉入猝死狀態(tài)
            System.out.println(
                    String.format("當前時間為: %s,發(fā)現(xiàn)人已猝死!—— 【 %s 】",
                            work.getHour(), work.getWorkState().getClass().getSimpleName()));
        }
    }
}


/**
 * description:  客戶端測試類
 *              todo 注: 該代碼有執(zhí)行順序的要求,僅做示例
 */
public class Test {
    public static void main(String[] args) {
        Work work = new Work();

        work.setHour(10);
        work.programming();
        System.out.println();

        work.setHour(13);
        work.programming();
        System.out.println();

        work.setHour(15);
        work.programming();
        System.out.println();

        work.setHour(18);
        work.programming();
        System.out.println();

        work.setHour(21);
        work.programming();
        System.out.println();

        work.setHour(6);
        work.programming();
        System.out.println();

        work.setHour(10);
        work.programming();
        System.out.println();

    }
}

運行結果

當前時間為: 10.0,精神狀態(tài)很好,效率很高!—— 【 MorningState 】

當前時間為: 13.0,剛吃飽,有點困!—— 【 NoonState 】

當前時間為: 15.0,中午沒睡,有點疲倦,效率不高!—— 【 AfterNoonState 】

當前時間為: 18.0,快到晚飯時間了,有點餓了!—— 【 EveningState 】

當前時間為: 21.0,領導不讓下班,非給找點活!—— 【 WorkOvertimeState 】

當前時間為: 6.0,發(fā)現(xiàn)人已猝死!—— 【 SuddenDeathState 】

當前時間為: 10.0,發(fā)現(xiàn)人已猝死!—— 【 SuddenDeathState 】

三、優(yōu)缺點

  • 缺點
    1.狀態(tài)多的業(yè)務場景導致累的數(shù)目增加,系統(tǒng)變復雜

  • 優(yōu)點
    1.將不同狀態(tài)隔離
    2.把各種狀態(tài)的轉換邏輯,分不到State的子類中,減少相互間的依賴
    3.增加新的狀態(tài)非常簡單

四、使用場景

1. 概括描述

  • 它主要解決的是,當控制一個對象狀態(tài)轉換的過程(比如判斷條件)比較復雜時,我們可以把狀態(tài)的判斷邏輯,放到表示不同狀態(tài)的一系列類當中,可以把復雜的判斷邏輯簡化。換句話說,可以理解為當一個對象的行為取決于他的狀態(tài),并且他必須在運行時根據(jù)他的狀態(tài)改變他的行為時,就可以考慮使用狀態(tài)模式了。

2. 現(xiàn)存知名產(chǎn)品中的使用示例 todo

2.1 javax.faces.lifecycle (jsf)

五、相關設計模式

1. 狀態(tài)模式與享元模式

在一些狀態(tài)對象可復用的地方,他們有時候時可以配合起來一起使用的。

六、參考

  1. https://coding.imooc.com/learn/list/270.html(強烈推薦)
  2. https://en.wikipedia.org/wiki/Design_Patterns
  3. 大話設計模式,電子版下載鏈接,https://pan.baidu.com/s/17WOI3Bvp-JUoQXvaomHISg 密碼:vw05
    (作者博客,https://www.cnblogs.com/cj723/archive/2007/12/30/1021314.html)
  4. https://www.cnblogs.com/geek6/p/3951677.html
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容