源碼地址 | https://github.com/DingMouRen/DesignPattern |
---|
狀態(tài)模式.png
- State定義一個或一組接口,表示該狀態(tài)下的行為
- ConcreteState具體狀態(tài)子類茶鉴,每一個具體的狀態(tài)類實現(xiàn)抽象State中定義的接口锋玲,從未達到不同狀態(tài)下的不同行為。
定義
狀態(tài)模式:當一個對象的內(nèi)在狀態(tài)改變時允許改變其行為涵叮,對象看起來似乎修改了它的類
使用場景
- 一個對象的行為取決于它的狀態(tài)惭蹂,并且它必須在運行時根據(jù)狀態(tài)改變它的行為
- 代碼中包含大量與對象狀態(tài)相關(guān)的條件語句
舉個栗子
我們電視機有開機和關(guān)機兩種狀態(tài),開機狀態(tài)可以做很多割粮,你懂的盾碗,關(guān)機狀態(tài)的話就什么也做不了。
//狀態(tài)的抽象接口類:電視狀態(tài)接口
public interface TvState {
void nextChannel();
void preChannel();
void turnUp();
void turnDown();
}
//具體狀態(tài)類:開機狀態(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)機狀態(tài)
public class PowerOffState implements TvState{
@Override
public void nextChannel() {
System.out.println("處于關(guān)機狀態(tài)舀瓢,關(guān)機在屏幕上是沒有提示的哦");
}
@Override
public void preChannel() {
System.out.println("處于關(guān)機狀態(tài)置尔,關(guān)機在屏幕上是沒有提示的哦");
}
@Override
public void turnUp() {
System.out.println("處于關(guān)機狀態(tài),關(guān)機在屏幕上是沒有提示的哦");
}
@Override
public void turnDown() {
System.out.println("處于關(guān)機狀態(tài)氢伟,關(guān)機在屏幕上是沒有提示的哦");
}
}
//電視遙控器
public class ControllerTv {
private TvState tvState;//持有狀態(tài)類的引用榜轿,便于調(diào)用狀態(tài)類的方法
//設置狀態(tài)
private void setTvState(TvState tvState) {
this.tvState = tvState;
}
//設置開機狀態(tài)
public void powerOn(){
setTvState(new PowerOnState());
System.out.println("開機咯");
}
//設置關(guān)機狀態(tài)
public void powerOff(){
setTvState(new PowerOffState());
System.out.println("關(guān)機了,歡迎再來哈");
}
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();
//設置開機狀態(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)類族砸烦,在避免代碼膨脹的同時也保證了可擴展性與可維護性弃鸦。
缺點:
State模式的使用必然會增加系統(tǒng)類和對象的個數(shù)