1银室、概念
狀態(tài)模式允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為浙于,對(duì)象看起來(lái)似乎修改了它所屬的類,屬于行為型模式跑慕。
未命名文件(5).png
2、模式結(jié)構(gòu)
- 環(huán)境角色(Context):定義客戶端所感興趣的接口摧找,并且保留一個(gè)具體狀態(tài)類的實(shí)例相赁。這個(gè)具體狀態(tài)類的實(shí)例給出此環(huán)境對(duì)象的現(xiàn)有狀態(tài)。
- 抽象狀態(tài)角色(State):定義一個(gè)接口慰于,用以封裝環(huán)境(Context)對(duì)象的一個(gè)特定的狀態(tài)所對(duì)應(yīng)的行為钮科。
- 具體狀態(tài)角色(ConcreteState):每一個(gè)具體狀態(tài)類都實(shí)現(xiàn)了環(huán)境(Context)的一個(gè)狀態(tài)所對(duì)應(yīng)的行為。
3婆赠、使用場(chǎng)景
- 對(duì)象的行為依賴于它的某些屬性值绵脯,狀態(tài)的改變將導(dǎo)致行為的變化
- 在代碼中包含大量與對(duì)象狀態(tài)有關(guān)的條件語(yǔ)句,這些條件語(yǔ)句的出現(xiàn)休里,會(huì)導(dǎo)致代碼的可維護(hù)性和靈活性變差蛆挫,不能方便地增加和刪除狀態(tài),并且導(dǎo)致客戶類與類庫(kù)之間的耦合增強(qiáng)
4妙黍、優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 封裝了轉(zhuǎn)換規(guī)則
- 枚舉可能的狀態(tài)悴侵,在枚舉狀態(tài)之前需要確定狀態(tài)種類
- 將所有與某個(gè)狀態(tài)有關(guān)的行為放到一個(gè)類中,并且可以方便地增加新的狀態(tài)拭嫁,只需要改變對(duì)象狀態(tài)即可改變對(duì)象的行為
- 允許狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對(duì)象合成一體可免,而不是某一個(gè)巨大的條件語(yǔ)句塊
- 可以讓多個(gè)環(huán)境對(duì)象共享一個(gè)狀態(tài)對(duì)象,從而減少系統(tǒng)中對(duì)象的個(gè)數(shù)
缺點(diǎn):
- 增加系統(tǒng)類和對(duì)象的個(gè)數(shù)
- 結(jié)構(gòu)與實(shí)現(xiàn)都較為復(fù)雜做粤,如果使用不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂
- 對(duì)"開(kāi)閉原則"的支持并不太好浇借,對(duì)于可以切換狀態(tài)的狀態(tài)模式,增加新的狀態(tài)類需要修改那些負(fù)責(zé)狀態(tài)轉(zhuǎn)換的源代碼怕品,否則無(wú)法切換到新增狀態(tài)妇垢,而且修改某個(gè)狀態(tài)類的行為也需修改對(duì)應(yīng)類的源代碼
5、實(shí)例
定義抽象狀態(tài)角色ConnectState
public interface ConnectState {
void handleAction();
}
定義具體狀態(tài)角色ReconnectState
public class ReconnectState implements ConnectState {
@Override
public void handleAction() {
// 重連邏輯
}
}
定義具體狀態(tài)角色SuccessState
public class SuccessState implements ConnectState {
@Override
public void handleAction() {
// 成功邏輯
}
}
定義具體狀態(tài)角色FailureState
public class FailureState implements ConnectState {
@Override
public void handleAction() {
// 失敗邏輯
}
}
定義環(huán)境角色Context
public class Context {
private ReconnectState reconnectState;
private FailureState failureState;
private SuccessState successState;
public void reconnect() {
if (reconnectState == null) {
reconnectState = new ReconnectState();
}
reconnectState.handleAction();
}
public void failure() {
if (failureState == null) {
failureState = new FailureState();
}
failureState.handleAction();
}
public void success() {
if (successState == null) {
successState = new SuccessState();
}
successState.handleAction();
}
}