日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java设计模式之行为型:状态模式

發(fā)布時間:2024/9/30 java 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java设计模式之行为型:状态模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

背景:

????????介紹狀態(tài)模式前,我們先看這樣一個實例:公司力排萬難終于獲得某個酒店的系統(tǒng)開發(fā)項目,并且最終落到了你的頭上。下圖是他們系統(tǒng)的主要工作:

????????當?shù)谝谎劭吹竭@個系統(tǒng)時你就看出這是一個狀態(tài)圖,每個框都代表了房間的狀態(tài),箭頭表示房間狀態(tài)的轉(zhuǎn)換。分析如下:房間有三個狀態(tài):空閑、已預(yù)訂、已入住,狀態(tài)與狀態(tài)之間可以根據(jù)客戶的動作來進行轉(zhuǎn)換,定義每個狀態(tài)的值。

public static final int FREEMTIME_STATE = 0; //空閑狀態(tài)public static final int BOOKED_STATE = 1; //已預(yù)訂狀態(tài)public static final int CHECKIN_STATE = 2; //入住狀態(tài)int state = FREEMTIME_STATE; //初始狀態(tài)

????????通過客戶的動作將每個狀態(tài)整合起來,實現(xiàn)這個功能最簡單的方式肯定是 if…else 啦!所以這里我們就通過動作將所有的狀態(tài)全面整合起來。分析得這里有四個動作:預(yù)訂、入住、退訂、退房。如下:

/*** @desc 預(yù)訂*/public void bookRoom(){if(state == FREEMTIME_STATE){ //空閑可預(yù)訂if(count > 0){System.out.println("空閑房間,完成預(yù)訂...");state = BOOKED_STATE; //改變狀態(tài):已預(yù)訂count --;//房間預(yù)訂完了,提示客戶沒有房源了if(count == 0){System.out.println("不好意思,房間已經(jīng)預(yù)訂完,歡迎您下次光臨...");}}else{System.out.println("不好意思,已經(jīng)沒有房間了....");}}else if(state == BOOKED_STATE){System.out.println("該房間已經(jīng)被預(yù)訂了...");}else if(state == CHECKIN_STATE){System.out.println("該房間已經(jīng)有人入住了...");}}/*** @desc 入住*/public void checkInRoom(){if(state == FREEMTIME_STATE){if(count > 0){System.out.println("空閑房間,入住...");state = CHECKIN_STATE; //改變狀態(tài):已預(yù)訂count --;//房間預(yù)訂完了,提示客戶沒有房源了if(count == 0){System.out.println("不好意思,房間已經(jīng)預(yù)訂完,歡迎您下次光臨...");}}else{System.out.println("不好意思,已經(jīng)沒有房間了....");}}else if(state == BOOKED_STATE){if("如果該房間是您預(yù)訂的"){System.out.println("入住....");state = CHECKIN_STATE;}else{System.out.println("您沒有預(yù)訂該房間,請先預(yù)訂...");}}else if(state == CHECKIN_STATE){System.out.println("該房間已經(jīng)入住了...");}}/*** @desc 退訂*/public void unsubscribeRoom(){if(state == FREEMTIME_STATE){}else if(state == CHECKIN_STATE){}else if(state == BOOKED_STATE){System.out.println("已退訂房間...");state = FREEMTIME_STATE;count ++;}}/*** @desc 退房*/public void checkOutRoom(){if(state == FREEMTIME_STATE){}else if(state == BOOKED_STATE){}else if(state == CHECKIN_STATE){System.out.println("已退房..");state = FREEMTIME_STATE;count++;}}

????????正當你完成這個 “復(fù)雜” 的 if..else 時,客戶增加需求說需要將某些房間保留下來以作為備用(standbyState),于是悲劇了,因為你發(fā)現(xiàn)要在所有的操作里都要判斷該房間是否為備用房間。當你老大經(jīng)過你身邊的時候發(fā)現(xiàn)你正在糾結(jié)怎么改的時候,你老大就問你為什么不換一個角度思考以狀態(tài)為原子來改變它的行為,而不是通過行為來改變狀態(tài)呢?于是你就學到了狀態(tài)模式。

一、什么是狀態(tài)模式:

? ? ? ? 狀態(tài)模式,就是允許對象在內(nèi)部狀態(tài)發(fā)生改變時改變它的行為,對象看起來就好像修改了它的類,也就是說以狀態(tài)為原子來改變它的行為,而不是通過行為來改變狀態(tài)。

? ? ? ? 當對象的行為取決于它的屬性時,我們稱這些屬性為狀態(tài),那該對象就稱為狀態(tài)對象。對于狀態(tài)對象而言,它的行為依賴于它的狀態(tài),比如要預(yù)訂房間,只有當該房間空閑時才能預(yù)訂,想入住該房間也只有當你預(yù)訂了該房間或者該房間為空閑時。對于這樣的一個對象,當它的外部事件產(chǎn)生互動的時候,其內(nèi)部狀態(tài)就會發(fā)生變化,從而使得他的行為也隨之發(fā)生變化。

????????

二、UML結(jié)構(gòu)圖:

  • Context:環(huán)境類,可以包括一些內(nèi)部狀態(tài)
  • State:抽象狀態(tài)類,定義了所有具體狀態(tài)的共同接口,任何狀態(tài)都需要實現(xiàn)這個接口,從而實現(xiàn)狀態(tài)間的互相轉(zhuǎn)換
  • ConcreteState:具體狀態(tài)類,處理來自 Context 的請求,每一個 ConcreteState 都提供了它對自己請求的實現(xiàn),所以,當 Context 改變狀態(tài)時行為也會跟著改變

從上面的UML結(jié)構(gòu)圖我們可以看出狀態(tài)模式的優(yōu)點在于:

(1)封裝了轉(zhuǎn)換規(guī)則,允許狀態(tài)轉(zhuǎn)換邏輯與狀態(tài)對象合成一體,而不是某一個巨大的條件語句塊

(2)將所有與狀態(tài)有關(guān)的行為放到一個類中,可以方便地增加新的狀態(tài),只需要改變對象狀態(tài)即可改變對象的行為。?

但是狀態(tài)模式的缺點在于:

(1)需要在枚舉狀態(tài)之前需要確定狀態(tài)種類

(2)會導(dǎo)致增加系統(tǒng)類和對象的個數(shù)。

(3)對 “開閉原則” 的支持并不友好,新增狀態(tài)類需要修改那些負責狀態(tài)轉(zhuǎn)換的源代碼,否則無法切換到新增狀態(tài);而且修改某個狀態(tài)類的行為也需修改對應(yīng)類的源代碼。

所以狀態(tài)模式適用于:代碼中包含大量與對象狀態(tài)有關(guān)的條件語句,以及對象的行為依賴于它的狀態(tài),并且可以根據(jù)它的狀態(tài)改變而改變它的相關(guān)行為。

策略模式和狀態(tài)模式比較:策略模式和狀態(tài)模式的結(jié)構(gòu)幾乎完全一致,但是它們的目的和本質(zhì)完全不一樣。策略模式是圍繞可以互換的算法來創(chuàng)建業(yè)務(wù)的,而狀態(tài)模式是通過改變對象內(nèi)部的狀態(tài)來幫助對象控制自己行為的。前者行為是彼此獨立、可以相互替換的,后者行為是不可以相互替換的。

三、代碼實現(xiàn):

以前面的酒店的案例進行代碼實現(xiàn),對于該實例的UML圖如下:

首先是狀態(tài)接口:State

public interface State {/*** @desc 預(yù)訂房間*/public void bookRoom();/*** @desc 退訂房間*/public void unsubscribeRoom();/*** @desc 入住*/public void checkInRoom();/*** @desc 退房*/public void checkOutRoom();}

然后是房間類:

public class Room {/** 房間的三個狀態(tài)*/State freeTimeState; //空閑狀態(tài)State checkInState; //入住狀態(tài)State bookedState; //預(yù)訂狀態(tài)State state ; public Room(){freeTimeState = new FreeTimeState(this);checkInState = new CheckInState(this);bookedState = new BookedState(this);state = freeTimeState ; //初始狀態(tài)為空閑}/*** @desc 預(yù)訂房間*/public void bookRoom(){state.bookRoom();}/*** @desc 退訂房間*/public void unsubscribeRoom(){state.unsubscribeRoom();}/*** @desc 入住*/public void checkInRoom(){state.checkInRoom();}/*** @desc 退房*/public void checkOutRoom(){state.checkOutRoom();}public String toString(){return "該房間的狀態(tài)是:"+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個狀態(tài)類,這個三個狀態(tài)分別對于這:空閑、預(yù)訂、入住。其中空閑可以完成預(yù)訂和入住兩個動作,預(yù)訂可以完成入住和退訂兩個動作,入住可以退房。

/** * @Description: 空閑狀態(tài)只能預(yù)訂和入住*/ public class FreeTimeState implements State {Room hotelManagement;public FreeTimeState(Room hotelManagement){this.hotelManagement = hotelManagement;}public void bookRoom() {System.out.println("您已經(jīng)成功預(yù)訂了...");hotelManagement.setState(hotelManagement.getBookedState()); //狀態(tài)變成已經(jīng)預(yù)訂}public void checkInRoom() {System.out.println("您已經(jīng)成功入住了...");hotelManagement.setState(hotelManagement.getCheckInState()); //狀態(tài)變成已經(jīng)入住}public void checkOutRoom() {//不需要做操作}public void unsubscribeRoom() {//不需要做操作} } /** * @Description: 入住狀態(tài)房間只能退房*/ public class BookedState implements State {Room hotelManagement;public BookedState(Room hotelManagement) {this.hotelManagement = hotelManagement;}public void bookRoom() {System.out.println("該房間已近給預(yù)定了...");}public void checkInRoom() {System.out.println("入住成功..."); hotelManagement.setState(hotelManagement.getCheckInState()); //狀態(tài)變成入住}public void checkOutRoom() {//不需要做操作}public void unsubscribeRoom() {System.out.println("退訂成功,歡迎下次光臨...");hotelManagement.setState(hotelManagement.getFreeTimeState()); //變成空閑狀態(tài)} } /** * @Description: 入住可以退房*/ public class CheckInState implements State {Room hotelManagement;public CheckInState(Room hotelManagement) {this.hotelManagement = hotelManagement;}public void bookRoom() {System.out.println("該房間已經(jīng)入住了...");}public void checkInRoom() {System.out.println("該房間已經(jīng)入住了...");}public void checkOutRoom() {System.out.println("退房成功....");hotelManagement.setState(hotelManagement.getFreeTimeState()); //狀態(tài)變成空閑}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(); //預(yù)訂rooms[0].checkInRoom(); //入住rooms[0].bookRoom(); //預(yù)訂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]);} }

運行結(jié)果:


?設(shè)計模式系列文章:

Java設(shè)計模式之創(chuàng)建型:工廠模式詳解(簡單工廠+工廠方法+抽象工廠)

Java設(shè)計模式之創(chuàng)建型:建造者模式

Java設(shè)計模式之創(chuàng)建型:單例模式

Java設(shè)計模式之創(chuàng)建型:原型模式

Java設(shè)計模式之結(jié)構(gòu)型:適配器模式

Java設(shè)計模式之結(jié)構(gòu)型:裝飾器模式

Java設(shè)計模式之結(jié)構(gòu)型:代理模式

Java設(shè)計模式之結(jié)構(gòu)型:橋接模式

Java設(shè)計模式之結(jié)構(gòu)型:外觀模式

Java設(shè)計模式之結(jié)構(gòu)型:組合模式

Java設(shè)計模式之結(jié)構(gòu)型:享元模式

Java設(shè)計模式之行為型:策略模式

Java設(shè)計模式之行為型:模板方法模式

Java設(shè)計模式之行為型:責任鏈模式

Java設(shè)計模式之行為型:觀察者模式

Java設(shè)計模式之行為型:訪問者模式

Java設(shè)計模式之行為型:中介者模式

Java設(shè)計模式之行為型:命令模式

Java設(shè)計模式之行為型:狀態(tài)模式

Java設(shè)計模式之行為型:備忘錄模式

Java設(shè)計模式之行為型:迭代器模式

Java設(shè)計模式之行為型:解釋器模式


原博客鏈接:設(shè)計模式讀書筆記-----狀態(tài)模式_chenssy 的技術(shù)博客-CSDN博客

總結(jié)

以上是生活随笔為你收集整理的Java设计模式之行为型:状态模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。