<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 引入 在閻宏博士的《JAVA與模式》一書中開頭是這樣描述狀態(State)模式的: > 狀態模式,又稱狀態對象模式(Pattern of Objects for States),狀態模式是對象的行為模式。 狀態模式允許一個對象在其內部狀態改變的時候改變其行為。這個對象看上去就像是改變了它的類一樣。 ## 定義 在很多情況下,一個對象的行為取決于它的一個或多個變化的屬性,這些屬性我們稱之為狀態,這個對象稱之為狀態對象。對于狀態對象而已,它的行為依賴于它的狀態,比如你要預訂房間,那么只有當該房間為空閑時你才能預訂,你想入住該房間也只有當你預訂了該房間或者該房間為空閑時。對于這樣的一個對象,當它在于外部事件產生互動的時候,其內部狀態就會發生改變,從而使得他的行為也隨之發生改變。 那么何為狀態模式呢?所謂狀態模式就是允許對象在內部狀態發生改變時改變它的行為,對象看起來好像修改了它的類。 ## 結構 用一句話來表述,狀態模式把所研究的對象的行為包裝在不同的狀態對象里,每一個狀態對象都屬于一個抽象狀態類的一個子類。狀態模式的意圖是讓一個對象在其內部狀態改變的時候,其行為也隨之改變。狀態模式的示意性類圖如下所示: ![](https://box.kancloud.cn/210b77bae67ec1f338bde6a4f64ed191_506x205.png) 狀態模式所涉及到的角色有: * 環境(Context)角色,也成上下文:定義客戶端所感興趣的接口,并且保留一個具體狀態類的實例。這個具體狀態類的實例給出此環境對象的現有狀態。 * 抽象狀態(State)角色:定義一個接口,用以封裝環境(Context)對象的一個特定的狀態所對應的行為。 * 具體狀態(ConcreteState)角色:每一個具體狀態類都實現了環境(Context)的一個狀態所對應的行為。 ## 認識狀態模式 **狀態和行為** 所謂對象的狀態,通常指的就是對象實例的屬性的值;而行為指的就是對象的功能,再具體點說,行為大多可以對應到方法上。 狀態模式的功能就是分離狀態的行為,通過維護狀態的變化,來調用不同狀態對應的不同功能。也就是說,狀態和行為是相關聯的,它們的關系可以描述為:狀態決定行為。 由于狀態是在運行期被改變的,因此行為也會在運行期根據狀態的改變而改變。 **行為的平行性** 注意平行線而不是平等性。所謂平行性指的是各個狀態的行為所處的層次是一樣的,相互獨立的、沒有關聯的,是根據不同的狀態來決定到底走平行線的哪一條。行為是不同的,當然對應的實現也是不同的,相互之間是不可替換的。 ![](https://box.kancloud.cn/3a84dcd833cede9072f151e7f1daf728_608x174.png) 而平等性強調的是可替換性,大家是同一行為的不同描述或實現,因此在同一個行為發生的時候,可以根據條件挑選任意一個實現來進行相應的處理。 ![](https://box.kancloud.cn/cefe99f857cf1017a5abecb04f9fbec7_399x228.png) 大家可能會發現狀態模式的結構和策略模式的結構完全一樣,但是,它們的目的、實現、本質卻是完全不一樣的。還有行為之間的特性也是狀態模式和策略模式一個很重要的區別,狀態模式的行為是平行性的,不可相互替換的;而策略模式的行為是平等性的,是可以相互替換的。 **環境和狀態處理對象** 在狀態模式中,環境(Context)是持有狀態的對象,但是環境(Context)自身并不處理跟狀態相關的行為,而是把處理狀態的功能委托給了狀態對應的狀態處理類來處理。 在具體的狀態處理類中經常需要獲取環境(Context)自身的數據,甚至在必要的時候會回調環境(Context)的方法,因此,通常將環境(Context)自身當作一個參數傳遞給具體的狀態處理類。 客戶端一般只和環境(Context)交互。客戶端可以用狀態對象來配置一個環境(Context),一旦配置完畢,就不再需要和狀態對象打交道了。客戶端通常不負責運行期間狀態的維護,也不負責決定后續到底使用哪一個具體的狀態處理對象。 ## 代碼實現 首先是狀態接口:State ``` public interface State { /** * @desc 預訂房間 * @return void */ public void bookRoom(); /** * @desc 退訂房間 * @return void */ public void unsubscribeRoom(); /** * @desc 入住 * @return void */ public void checkInRoom(); /** * @desc 退房 * @return void */ public void checkOutRoom(); } ``` 然后是房間類 ``` public class Room { /* * 房間的三個狀態 */ State freeTimeState; //空閑狀態 State checkInState; //入住狀態 State bookedState; //預訂狀態 State state ; public Room(){ freeTimeState = new FreeTimeState(this); checkInState = new CheckInState(this); bookedState = new BookedState(this); state = freeTimeState ; //初始狀態為空閑 } /** * @desc 預訂房間 * @return void */ public void bookRoom(){ state.bookRoom(); } /** * @desc 退訂房間 * @return void */ public void unsubscribeRoom(){ state.unsubscribeRoom(); } /** * @desc 入住 * @return void */ public void checkInRoom(){ state.checkInRoom(); } /** * @desc 退房 * @return void */ public void checkOutRoom(){ state.checkOutRoom(); } public String toString(){ return "該房間的狀態是:"+getState().getClass().getName(); } /* * getter和setter方法 */ public State getFreeTimeState() { return freeTimeState; } public void setFreeTimeState(State freeTimeState) { this.freeTimeState = freeTimeState; } public State getCheckInState() { return checkInState; } public void setCheckInState(State checkInState) { this.checkInState = checkInState; } public State getBookedState() { return bookedState; } public void setBookedState(State bookedState) { this.bookedState = bookedState; } public State getState() { return state; } public void setState(State state) { this.state = state; } } ``` 然后是3個狀態類,這個三個狀態分別對于這:空閑、預訂、入住。其中空閑可以完成預訂和入住兩個動作,預訂可以完成入住和退訂兩個動作,入住可以退房。 ``` /** * @Description: 空閑狀態只能預訂和入住 */ public class FreeTimeState implements State { Room hotelManagement; public FreeTimeState(Room hotelManagement){ this.hotelManagement = hotelManagement; } public void bookRoom() { System.out.println("您已經成功預訂了..."); hotelManagement.setState(hotelManagement.getBookedState()); //狀態變成已經預訂 } public void checkInRoom() { System.out.println("您已經成功入住了..."); hotelManagement.setState(hotelManagement.getCheckInState()); //狀態變成已經入住 } public void checkOutRoom() { //不需要做操作 } public void unsubscribeRoom() { //不需要做操作 } } ``` ``` /** * @Description: 入住狀態房間只能退房 */ public class BookedState implements State { Room hotelManagement; public BookedState(Room hotelManagement) { this.hotelManagement = hotelManagement; } public void bookRoom() { System.out.println("該房間已近給預定了..."); } public void checkInRoom() { System.out.println("入住成功..."); hotelManagement.setState(hotelManagement.getCheckInState()); //狀態變成入住 } public void checkOutRoom() { //不需要做操作 } public void unsubscribeRoom() { System.out.println("退訂成功,歡迎下次光臨..."); hotelManagement.setState(hotelManagement.getFreeTimeState()); //變成空閑狀態 } } ``` ``` /** * @Description: 入住可以退房 */ public class CheckInState implements State { Room hotelManagement; public CheckInState(Room hotelManagement) { this.hotelManagement = hotelManagement; } public void bookRoom() { System.out.println("該房間已經入住了..."); } public void checkInRoom() { System.out.println("該房間已經入住了..."); } public void checkOutRoom() { System.out.println("退房成功...."); hotelManagement.setState(hotelManagement.getFreeTimeState()); //狀態變成空閑 } public void unsubscribeRoom() { //不需要做操作 } } ``` 最后是測試類 ``` public class Test { public static void main(String[] args) { //有3間房 Room[] rooms = new Room[2]; //初始化 for(int i = 0 ; i < rooms.length ; i++){ rooms[i] = new Room(); } //第一間房 rooms[0].bookRoom(); //預訂 rooms[0].checkInRoom(); //入住 rooms[0].bookRoom(); //預訂 System.out.println(rooms[0]); System.out.println("---------------------------"); //第二間房 rooms[1].checkInRoom(); rooms[1].bookRoom(); rooms[1].checkOutRoom(); rooms[1].bookRoom(); System.out.println(rooms[1]); } } ``` ## 優點 * 1、封裝了轉換規則。 * 2、枚舉可能的狀態,在枚舉狀態之前需要確定狀態種類。 * 3、將所有與某個狀態有關的行為放到一個類中,并且可以方便地增加新的狀態,只需要改變對象狀態即可改變對象的行為。 * 4、允許狀態轉換邏輯與狀態對象合成一體,而不是某一個巨大的條件語句塊。 * 5、可以讓多個環境對象共享一個狀態對象,從而減少系統中對象的個數。 ## 缺點 * 1、狀態模式的使用必然會增加系統類和對象的個數。 * 2、狀態模式的結構與實現都較為復雜,如果使用不當將導致程序結構和代碼的混亂。 * 3、狀態模式對“開閉原則”的支持并不太好,對于可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的源代碼,否則無法切換到新增狀態;而且修改某個狀態類的行為也需修改對應類的源代碼。 ## 適用場景 * 1、對象的行為依賴于它的狀態(屬性)并且可以根據它的狀態改變而改變它的相關行為。 * 2、代碼中包含大量與對象狀態有關的條件語句 ## 總結 * 1、狀態模式允許一個對象基于內部狀態而擁有不同的行為。 * 2、Context會將行為委托給當前狀態對象。 * 3、狀態模式對“開閉原則”支持不是很好
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看