介紹
狀態(tài)模式的行為是由狀態(tài)來決定的,不同狀態(tài)下有不同的行為尿招。
-
狀態(tài)模式和策略模式的結(jié)構(gòu)幾乎完全一樣矾柜,但是他們的目的,本質(zhì)卻完全不一樣:
區(qū)別: 狀態(tài)模式的行為是平行的就谜,不可替換的怪蔑,策略模式的行為是彼此獨(dú)立,可以相互替換的
描述:狀態(tài)模式把對(duì)象的行為包裝在不同的狀態(tài)對(duì)象里丧荐,每一個(gè)狀態(tài)對(duì)象都有一個(gè)共同的抽象狀態(tài)積累缆瓣。狀態(tài)模式的意圖是讓每一個(gè)對(duì)象在其內(nèi)部 狀態(tài)改變的時(shí)候,行為也隨之改變
定義
當(dāng)一個(gè)對(duì)象內(nèi)的轉(zhuǎn)改改變時(shí)虹统,允許改變其行為弓坞,這個(gè)對(duì)象看起來像是改變了其類
使用場(chǎng)景
- 一個(gè)對(duì)象的行為取決于他的狀態(tài),并且他必須在運(yùn)行時(shí)根據(jù)狀態(tài)改變他的行為
- 代碼中大量與狀態(tài)有關(guān)的語句窟却,例如:一個(gè)操作中含有龐大的分支語句昼丑,且這些分支依賴于該對(duì)象的狀態(tài)
- 狀態(tài)模式將每一個(gè)條件分支放入一個(gè)獨(dú)立的類中,這使得你可以根據(jù)對(duì)象自身的情況將對(duì)象的狀態(tài)作為一個(gè)對(duì)象夸赫,這一對(duì)象可以不依賴其他對(duì)象而獨(dú)立變化菩帝,這樣通過多態(tài)來去除過多的,重復(fù)的 if-else 分支語句
UML圖解 (待補(bǔ)充)
代碼示例
- 普通實(shí)現(xiàn)
public class TvController {
private static int BASE_STATE = 0;
private final static int POWER_OFF = BASE_STATE + 1;
private final static int POWER_ON = BASE_STATE + 2;
private int mState = POWER_OFF;
public void powerOn() {
mState = POWER_ON;
if (mState == POWER_OFF) {
System.out.println("開機(jī)");
}
}
public void powerOff() {
mState = POWER_OFF;
if (mState == POWER_ON) {
System.out.println("關(guān)機(jī)");
}
}
public void nextChannel() {
if (mState == POWER_ON) {
System.out.println("下一個(gè)頻道");
} else {
System.out.println("error tv is powerOff !!");
}
}
public void prevChannel() {
if (mState == POWER_ON) {
System.out.println("上一個(gè)頻道");
} else {
System.out.println("error tv is powerOff !!");
}
}
public void turnOn() {
if (mState == POWER_ON) {
System.out.println("調(diào)高音量");
} else {
System.out.println("error tv is powerOff !!");
}
}
public void turnDown() {
if (mState == POWER_ON) {
System.out.println("調(diào)低音量");
} else {
System.out.println("error tv is powerOff !!");
}
}
}
可以看到茬腿,在TVController類中呼奢,通過mState來存儲(chǔ)電視的狀態(tài),并且在各個(gè)操作中都需要通過if-else來判斷狀態(tài)切平,代碼重復(fù)握础,相對(duì)較為混亂
- 狀態(tài)模式實(shí)現(xiàn)
使用狀態(tài)模式:將這些狀態(tài)用對(duì)象來代替,將這些行為封裝到對(duì)象中悴品,是的不同的狀態(tài)下有不同的實(shí)現(xiàn)禀综,這樣就將這些if-else 從TVController類
去掉简烘,整個(gè)代碼也看起來清晰起來。
- TvState.java : 抽象類 實(shí)現(xiàn)Tv相關(guān)操作
public interface TvState {
public void nextChannel();
public void prevChannel();
public void turnUp();
public void turnDown();
}
- PowerOffState.java :關(guān)機(jī)狀態(tài)實(shí)現(xiàn)類
public class PowerOfferState implements TvState {
@Override
public void nextChannel() {
}
@Override
public void prevChannel() {
}
@Override
public void turnOn() {
}
@Override
public void turnDown() {
}
}
- PowerOnState.java :開機(jī)狀態(tài)實(shí)現(xiàn)類
public class PowerOnState implements TvState {
@Override
public void nextChannel() {
print("下一頻道");
}
@Override
public void prevChannel() {
print("上一頻道");
}
@Override
public void turnOn() {
print("調(diào)高音量");
}
@Override
public void turnDown() {
print("調(diào)低音量");
}
private void print(String msg) {
System.out.println(msg);
}
}
- PowerController.java : 開關(guān)機(jī)控制抽象類
public interface PowerController {
public TvState mState;
public void setState(TvState state);
public void powerOn();
public void powerOff();
}
- TvControllerImp.java
public class TvControllerImp implements PowerController {
@Override
public void setState(TvState state) {
mState = state;
}
@Override
public void powerOn() {
setState(new PowerOnState());
System.out.println("開機(jī)");
}
@Override
public void powerOff() {
setState(new PowerOffState());
System.out.println("關(guān)機(jī)");
}
public void nextChannel() {
mState.nextChannel();
}
public void prevChannel() {
mState.prevChannel();
}
public void turnOn() {
mState.turnOn();
}
public void turnDown() {
mState.turnDown();
}
}
- 測(cè)試代碼
public class TvClient {
public static void main(String[] args) {
TvControllerImp tv = new TvControllerImp();
// 開機(jī)
tv.powerOn();
// 下一個(gè)頻道
tv.nextChannel();
// 調(diào)高音量
tv.turnOn();
// 調(diào)低音量
tv.turnDown();
// 關(guān)機(jī)
tv.powerOff();
// 調(diào)高音量定枷,電視不響應(yīng)
tv.turnOn();
}
}
- Android中的應(yīng)用實(shí)例--WiFi管理