Java中的狀態模式實例教程
狀態模式是一種行為設計模式。適用於當對象的內在狀態改變它自身的行為時。
如果想基於對象的狀態來改變自身的行為,通常利用對象的狀態變量及if-else條件子句來扮演針對對象的不同行為。狀態模式Context(環境)和State(狀態)分離的方式既保證狀態與行為的聯動變化,又使得這種變化是條理明晰且鬆耦合的。
Context是包含了狀態引用的類,此引用指向一個狀態的具體實現。並且幫助把對狀態的請求委托給此狀態的對象進行處理。看一個具體的例子。
假如想實現電視遙控器,使用簡單按鍵來表現動作。如果狀態是ON,電視將被打開,如果狀態是OFF,電視將被關閉。
利用if-else條件子句來實現。
package com.journaldev.design.state;
public class TVRemoteBasic {
private String state="";
public void setState(String state){
this.state=state;
}
public void doAction(){
if(state.equalsIgnoreCase("ON")){
System.out.println("TV is turned ON");
}else if(state.equalsIgnoreCase("OFF")){
System.out.println("TV is turned OFF");
}
}
public static void main(String args[]){
TVRemoteBasic remote = new TVRemoteBasic();
remote.setState("ON");
remote.doAction();
remote.setState("OFF");
remote.doAction();
}
}
注意:客戶端代碼需要知道每一個不同的值所代表的遙控器的不同狀態。如果這樣,假如大量的狀態被增加,那麼對於被緊緊捆綁在一起的狀態實現以及相應的客戶端代碼,它們的維護及擴展就變得非常困難。
現在使用狀態模式實現上述電視控製器。
抽象State接口
首先創建一個狀態接口來定義一個方法,此方法需要被不同的具體狀態類以及環境類實現。
package com.journaldev.design.state;
public interface State {
public void doAction();
}
具體State實現
自此例子中,包含兩個狀態:一個是打開電視的狀態,一個關閉電視的狀態。因此,需要創建兩個具體狀態類代表這兩個行為。
package com.journaldev.design.state;
public class TVStartState implements State {
@Override
public void doAction() {
System.out.println("TV is turned ON");
}
}
package com.journaldev.design.state;
public class TVStopState implements State {
@Override
public void doAction() {
System.out.println("TV is turned OFF");
}
}
現在我們開始實現Context對象,能改基於內在對象來改變自身的行為。
Context類實現
package com.journaldev.design.state;
public class TVContext implements State {
private State tvState;
public void setState(State state) {
this.tvState=state;
}
public State getState() {
return this.tvState;
}
@Override
public void doAction() {
this.tvState.doAction();
}
}
注意,Context類實現了狀態以及保持了對此狀態的引用。它能夠把對此狀態的請求委托到某一具體狀態實現中。
測試程序
完成一個簡單地程序對使用狀態模式的電視遙控器的測試。
package com.journaldev.design.state;
public class TVRemote {
public static void main(String[] args) {
TVContext context = new TVContext();
State tvStartState = new TVStartState();
State tvStopState = new TVStopState();
context.setState(tvStartState);
context.doAction();
context.setState(tvStopState);
context.doAction();
}
}
上述程序的輸出與沒用使用任何設計模式的電視控製器的實現類似。
使用狀態設計模式的優勢就是實現多態性的過程是清晰可見的。狀態的改變中產生的錯誤也較少,另外增加更多的狀態以及行為變得容易且更具魯棒性。此外狀態模式也幫助避免if-else子句或者switch-case條件判定邏輯。
狀態模式類似於策略模式,請看Java中的策略模式。這就是全部的狀態設計模式,希望你喜歡上它了。
最後更新:2017-05-23 11:31:53