1. 程式人生 > >《Android源代碼設計模式解析與實戰》讀書筆記(八)

《Android源代碼設計模式解析與實戰》讀書筆記(八)

code androi nal clas 函數 轉發 類和對象 cti comment

第八章、狀態模式

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源代碼設計模式解析與實戰》讀書筆記(八)