- 一、導語
- 二、怎么用
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)對象可復用的地方,他們有時候時可以配合起來一起使用的。