標籤:設定 電源 多分支 指定 nts 封裝 roi 狀態改變 轉寄
第八章、狀態模式1.定義
狀態模式中的行為是由狀態來決定,不同的狀態下有不同的行為。當一個對象的內在狀態改變時同意改變其行為,這個對象看起來像是改變了其類。
2.使用情境
1.一個對象的行為取決於它的狀態,而且它必須在執行時依據狀態改變它的行為。
2.代碼中包括大量與對象狀態有關的條件陳述式,比如,一個操作中含有大量的多分支語句。且這些分支依賴於該對象的狀態。
3.簡單實現
實現效果:首先將電視的狀態分為開機與關機狀態,開機時能夠通過遙控器實現頻道切換和調節音量,可是關機時,這些操作都會失效。
首先是普通的實現方法:
public class TVController { //開機狀態 private final static int POWER_ON = 1; //關機狀態 private final static int POWER_OFF = 2; //預設狀態 private int mState = POWER_OFF; public void powerOn(){ if(mState ==POWER_OFF){ System.out.println("電視開機了"); } mState = POWER_ON; } public void powerOff(){ if(mState ==POWER_ON){ System.out.println("電視關機了"); } mState = POWER_OFF; } public void nextChannel(){ if(mState ==POWER_ON){ System.out.println("下一頻道"); }else{ System.out.println("沒有開機"); } } public void prevChannel(){ if(mState ==POWER_ON){ System.out.println("上一頻道"); }else{ System.out.println("沒有開機"); } } public void turnUp(){ if(mState ==POWER_ON){ System.out.println("調高音量"); }else{ System.out.println("沒有開機"); } } public void turnDown(){ if(mState ==POWER_ON){ System.out.println("調低音量"); }else{ System.out.println("沒有開機"); } }}
能夠看到,每次執行通過推斷目前狀態來進行操作。部分的代碼反覆。如果狀態和功能添加,就會越來越難以維護。這時能夠使用狀態模式。例如以下:
電視的操作
/** * 電視狀態介面,定義了電視的操作函數 * * */public interface TVState { public void nextChannel(); public void prevChannel(); public void turnUp(); public void turnDown();}
關機狀態
/** * * 關機狀態,操作無結果 * * */public class PowerOffState implements TVState{ @Override public void nextChannel() { } @Override public void prevChannel() { } @Override public void turnUp() { } @Override public void turnDown() { }}
開機狀態
/** * * 開機狀態。操作有效 * * */public class PowerOnState implements TVState{ @Override public void nextChannel() { System.out.println("下一頻道"); } @Override public void prevChannel() { System.out.println("上一頻道"); } @Override public void turnUp() { System.out.println("調高音量"); } @Override public void turnDown() { System.out.println("調低音量"); }}
電源操作介面
/** * 電源操作介面 * * */public interface PowerController { public void powerOn(); public void powerOff();}
電視遙控器
/** * 電視遙控器 * * */public class TVController implements PowerController{ TVState mTVState; public void setTVState(TVState mTVState){ this.mTVState = mTVState; } @Override public void powerOn() { setTVState(new PowerOnState()); System.out.println("開機了"); } @Override public void powerOff() { setTVState(new PowerOffState()); System.out.println("關機了"); } public void nextChannel(){ mTVState.nextChannel(); } public void prevChannel(){ mTVState.prevChannel(); } public void turnUp(){ mTVState.turnUp(); } public void turnDown(){ mTVState.turnDown(); }}
調用:
public class Client { public static void main(String[] args) { TVController tvController = new TVController(); //設定開機狀態 tvController.powerOn(); //下一頻道 tvController.nextChannel(); //調高音量 tvController.turnUp(); //關機 tvController.powerOff(); //調低音量,此時不會生效 tvController.turnDown(); }}
結果
開機了下一頻道調高音量關機了
能夠看出。狀態模式將這些行為封裝到狀態類中。在進行操作時將這些功能轉寄給狀態物件,不同的狀態有不同的實現,去除了反覆了if-else語句,這正是狀態模式的精髓所在。
4.與策略模式的差別
狀態模式與策略模式的結構差點兒是一樣的,就像是孿生兄弟。可是他們的目地、本質不一樣。
狀態模式的行為是平行的、不可替換的。策略模式的行為是彼此獨立的、可相互替換的。狀態模式,一般是自我控制狀態的改變。而策略模式,是由外部指定使用什麼樣的策略。
5.Android實戰中的使用
1.登入系統,依據使用者是否登入。推斷事件的處理方式。
2.Wi-Fi管理,在不同的狀態下,WiFi的掃描請求處理不一。
6.總結1.長處
將全部與一個特定的狀態相關的行為都放入一個狀態物件中,它提供了一個更好的方法來組織與特定狀態相關的代碼。將繁瑣的狀態推斷轉換成結構清晰的狀態類族。在避免代碼膨脹的同一時候也保證了可擴充性與可維護性。
2.缺點
狀態模式的使用必定會添加系統類別和對象的個數。
《Android原始碼設計模式解析與實戰》讀書筆記(八)