閱讀183 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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

  上一篇:go  Java IO: ByteArray和Filter
  下一篇:go  Java IO: Buffered和Data