| 源碼地址 | https://github.com/DingMouRen/DesignPattern |
|---|

狀態(tài)模式.png
- State定義一個或一組接口,表示該狀態(tài)下的行為
- ConcreteState具體狀態(tài)子類,每一個具體的狀態(tài)類實現(xiàn)抽象State中定義的接口,從未達(dá)到不同狀態(tài)下的不同行為。
定義
狀態(tài)模式:當(dāng)一個對象的內(nèi)在狀態(tài)改變時允許改變其行為,對象看起來似乎修改了它的類
使用場景
- 一個對象的行為取決于它的狀態(tài),并且它必須在運行時根據(jù)狀態(tài)改變它的行為
- 代碼中包含大量與對象狀態(tài)相關(guān)的條件語句
舉個栗子
我們電視機(jī)有開機(jī)和關(guān)機(jī)兩種狀態(tài),開機(jī)狀態(tài)可以做很多,你懂的,關(guān)機(jī)狀態(tài)的話就什么也做不了。
//狀態(tài)的抽象接口類:電視狀態(tài)接口
public interface TvState {
void nextChannel();
void preChannel();
void turnUp();
void turnDown();
}
//具體狀態(tài)類:開機(jī)狀態(tài)
public class PowerOnState implements TvState {
@Override
public void nextChannel() {
System.out.println(getClass().getSimpleName()+":下一個頻道");
}
@Override
public void preChannel() {
System.out.println(getClass().getSimpleName()+":上一個頻道");
}
@Override
public void turnUp() {
System.out.println(getClass().getSimpleName()+":調(diào)高音量");
}
@Override
public void turnDown() {
System.out.println(getClass().getSimpleName()+":調(diào)低音量");
}
}
//具體狀態(tài)類:關(guān)機(jī)狀態(tài)
public class PowerOffState implements TvState{
@Override
public void nextChannel() {
System.out.println("處于關(guān)機(jī)狀態(tài),關(guān)機(jī)在屏幕上是沒有提示的哦");
}
@Override
public void preChannel() {
System.out.println("處于關(guān)機(jī)狀態(tài),關(guān)機(jī)在屏幕上是沒有提示的哦");
}
@Override
public void turnUp() {
System.out.println("處于關(guān)機(jī)狀態(tài),關(guān)機(jī)在屏幕上是沒有提示的哦");
}
@Override
public void turnDown() {
System.out.println("處于關(guān)機(jī)狀態(tài),關(guān)機(jī)在屏幕上是沒有提示的哦");
}
}
//電視遙控器
public class ControllerTv {
private TvState tvState;//持有狀態(tài)類的引用,便于調(diào)用狀態(tài)類的方法
//設(shè)置狀態(tài)
private void setTvState(TvState tvState) {
this.tvState = tvState;
}
//設(shè)置開機(jī)狀態(tài)
public void powerOn(){
setTvState(new PowerOnState());
System.out.println("開機(jī)咯");
}
//設(shè)置關(guān)機(jī)狀態(tài)
public void powerOff(){
setTvState(new PowerOffState());
System.out.println("關(guān)機(jī)了,歡迎再來哈");
}
public void nextChannel(){
tvState.nextChannel();
}
public void preChannel(){
tvState.preChannel();
}
public void turnUp(){
tvState.turnUp();
}
public void turnDown(){
tvState.turnDown();
}
}
使用
public static void main(String[] args) {
//先獲取一個電視遙控器對象
ControllerTv controllerTv = new ControllerTv();
//設(shè)置開機(jī)狀態(tài)
controllerTv.powerOn();
//隨便玩耍
controllerTv.nextChannel();
controllerTv.turnUp();
controllerTv.powerOff();
controllerTv.nextChannel();
}
總結(jié)
狀態(tài)模式與策略模式的結(jié)構(gòu)幾乎是一樣的,但是狀態(tài)模式的行為是平行的,不可替換的;策略模式的行為是彼此獨立的,是可以相互替換的。
優(yōu)點:
State模式將所有與一個特定狀態(tài)相關(guān)的行為都放入一個具體狀態(tài)對象中,提供了一個更好的方法來組織與特定狀態(tài)相關(guān)的代碼,將繁瑣的狀態(tài)判斷換成結(jié)構(gòu)清晰的狀態(tài)類族,在避免代碼膨脹的同時也保證了可擴(kuò)展性與可維護(hù)性。
缺點:
State模式的使用必然會增加系統(tǒng)類和對象的個數(shù)