初學 Java 設計模式(二十):實戰狀態模式 「親身實踐,簡單高效的時間管理——番茄工做法」

1、狀態模式介紹

1. 解決的問題

主要解決在對象一個內部狀態發生變化時,改變其行爲的問題。java

2. 定義

狀態模式是一種行爲設計模式,讓你能在一個對象的內部狀態變化時改變其行爲,使其看上去就像改變了自身所屬的類同樣。git

3. 應用場景

  • 若是對象須要根據自身當前狀態進行不一樣行爲,同時狀態的數量很是多且與狀態相關的代碼會頻繁變動的話,可以使用狀態模式。
  • 若是某個類須要根據成員變量的當前值改變自身行爲,從而須要使用大量的條件語句時,可以使用狀態模式。
  • 當類似狀態和基於條件的狀態機轉換中存在許多重複代碼時,可以使用狀態模式。

2、狀態模式優缺點

1. 優勢

  • 單一職責原則:將與特色狀態相關的代碼放在單獨的類中。
  • 開閉原則:無需修改已有狀態類和上下文就能引入新狀態。
  • 經過消除臃腫的狀態機條件語句簡化上下文代碼。

2. 缺點

  • 若是狀態機只有不多的幾個狀態,或者不多發生改變,那麼應用該模式可能會顯得小題大作。

3、狀態模式應用實例:簡單高效的時間管理——番茄工做法

1. 實例場景

不知道你們有沒有常常想認真學習,卻一直晚會再說的狀況,我反正就是。github

最近發現了個番茄工做法,找了個軟件體驗了一下,聽着滴答滴答的工做背景音效,仍是頗有種時間在嘩啦嘩啦流的緊迫感,能必定程度上提升點效率,固然可能聽習慣了就不當回事了。設計模式

具體的軟件若是想要的話,評論留言告訴我。ide

番茄工做法是弗朗西斯科·西里洛在 1922 年建立的一種時間管理方法,有助於提升工做效率,養成良好的學習習慣。學習

它的基本原理就是把工做時間分爲多個番茄鍾,一個番茄鍾由 25 分鐘工做時間和 5 分鐘休息時間組成。測試

  • 25 分鐘的工做時間內,要保持專一,避免干擾。
  • 5 分鐘的休息時間建議離開工做區域,喝一杯茶,作一些簡單的伸展運動。優化

    這樣看是否是還有點護眼,讓咱們這些每天對着電腦的農民工能及時想起來本身的眼睛須要休息。設計

不少時候,感受忙了一天,也不知道本身在忙啥,也能夠用番茄工做法將本身的一天記錄下來,分析一下時間都去哪了?rest

今天,就以番茄工做法的工做狀態到休息狀態爲例,介紹一下狀態模式。

2. 狀態模式實現

2.1 工程結構
state-pattern
└─ src
    ├─ main
    │    └─ java
    │    └─ org.design.pattern.state
    │       ├─ model
    │       │    ├─ PomodoroState.java
    │       │    └─ impl
    │       │        ├─ WorkPomodoroState.java
    │       │        └─ RestPomodoroState.java
    │       └─ service
    │            ├─ PomodoroService.java
    │            └─ impl
    │                 └─ PomodoroServiceImpl.java
    └─ test
        └─ java
            └─ org.design.pattern.state.test
                  └─ PomodoroTest.java
2.2 代碼實現
2.2.1 實體類

番茄狀態接口

/**
 * 番茄狀態接口
 */
public interface PomodoroState {

    /**
     * 工做
     */
    void work();

    /**
     * 休息
     */
    void rest();
}

番茄-工做狀態類

/**
 * 番茄-工做狀態類
 */
@Slf4j
public class WorkPomodoroState implements PomodoroState {

    /**
     * 工做
     */
    @Override
    public void work() {
        log.info("工做中:請保持高度集中!");
    }

    /**
     * 休息
     */
    @Override
    public void rest() {
        log.info("工做狀態中斷:該番茄鍾做廢!");
    }
}

番茄-休息狀態類

/**
 * 番茄-休息狀態類
 */
@Slf4j
public class RestPomodoroState implements PomodoroState {

    /**
     * 工做
     */
    @Override
    public void work() {
        log.info("良好的休息纔是下一個番茄鍾開始的必要條件!");
    }

    /**
     * 休息
     */
    @Override
    public void rest() {
        log.info("工做時間結束了,喝杯水,伸個懶腰,看看窗外!");
    }
}
2.2.2 服務類

番茄工做法服務接口

/**
 * 番茄工做法服務接口
 */
public interface PomodoroService {

    /**
     * 開啓番茄
     */
    void openPomodoro();
}

番茄工做法服務實現類

/**
 * 番茄工做法服務實現類
 */
@Slf4j
public class PomodoroServiceImpl implements PomodoroService {

    /**
     * 開啓一次番茄
     */
    @Override
    public void openPomodoro() {
        // 番茄-工做時間
        PomodoroState workState = new WorkPomodoroState();
        log.info("開啓一次番茄時間");
        workState.work();
        log.info("工做時間想休息");
        workState.rest();
        log.info("工做時間結束");
        // 番茄-休息時間
        PomodoroState restState = new RestPomodoroState();
        restState.rest();
        log.info("休息時間想工做");
        restState.work();
        log.info("休息時間結束,準備好開始下一個番茄了嘛?");
     }
}
2.3 測試驗證
2.3.1 測試驗證類
/**
 * 番茄工做法測試類
 */
public class PomodoroTest {

    @Test
    public void test() {
        PomodoroService pomodoroService = new PomodoroServiceImpl();
        pomodoroService.openPomodoro();
    }
}
2.3.2 測試結果
15:07:06.447 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 開啓一次番茄時間
15:07:06.449 [main] INFO  o.d.p.s.model.impl.WorkPomodoroState - 工做中:請保持高度集中!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 工做時間想休息
15:07:06.449 [main] INFO  o.d.p.s.model.impl.WorkPomodoroState - 工做狀態中斷:該番茄鍾做廢!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 工做時間結束
15:07:06.449 [main] INFO  o.d.p.s.model.impl.RestPomodoroState - 工做時間結束了,喝杯水,伸個懶腰,看看窗外!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 休息時間想工做
15:07:06.449 [main] INFO  o.d.p.s.model.impl.RestPomodoroState - 良好的休息纔是下一個番茄鍾開始的必要條件!
15:07:06.449 [main] INFO  o.d.p.s.s.impl.PomodoroServiceImpl - 休息時間結束,準備好開始下一個番茄了嘛?

Process finished with exit code 0

4、狀態模式結構

狀態模式-模式結構圖

  1. 上下文(Context)保存了對於一個具體狀態對象的引用,並會將全部與該狀態相關的工做委派給它。上下文經過狀態接口與狀態對象交互,且會提供一個設置器用於傳遞新的狀態對象。
  2. 狀態(State)接口會聲明特定於狀態的方法,這些方法應能被其餘全部具體狀態所理解。
  3. 具體狀態(Concrete States)會自行實現特定於狀態的方法。爲了不多個狀態中包含類似代碼,能夠提供一個封裝有部分通用行爲的中間抽象類。

    狀態對象可存儲對於上下文對象的反向引用。狀態能夠經過該引用從上下文處獲取所需信息,而且能觸發狀態轉移。

  4. 上下文和具體狀態均可以設置上下文的下個狀態,並可經過替換鏈接到上下文的狀態對象來完成實際的狀態轉換。

設計模式並不難學,其自己就是多年經驗提煉出的開發指導思想,關鍵在於多加練習,帶着使用設計模式的思想去優化代碼,就能構建出更合理的代碼。

源碼地址:https://github.com/yiyufxst/design-pattern-java

參考資料:
小博哥重學設計模式:https://github.com/fuzhengwei/itstack-demo-design
深刻設計模式:https://refactoringguru.cn/design-patterns/catalog

相關文章
相關標籤/搜索