亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

在Java中應用State設計模式

2019-11-18 12:17:30
字體:
來源:轉載
供稿:網友

  對象的狀態由各個屬性的當前值構成。當我們調用某個對象的setXXX()方法時,通常表示修改它的XXX屬性。另外,對象在執行方法時,也可能修改自己的狀態。在某些情形下,例如建立事務或機器模型時,對象的狀態可能是決定其行為的要害因素,依靠于狀態的代碼邏輯可能遍布于類的大量方法。State模式的目標就是簡化這類代碼,把依靠于狀態的邏輯集中到一組類,每一個類代表一種不同的狀態,避免if語句嵌套過深或過于復雜,轉而依靠于多態性來調用不同的方法。
  狀態模型
  假如對象的狀態信息很要害,對象會擁有一些變量來指示如何根據狀態做出相應的動作。這些變量大量地散布于復雜的多層嵌套if語句中,來描述對象如何響應可能出現的事件。用這種方式建立對象模型的最大缺點在于if語句可能變得相當復雜一旦要修改對象的狀態模型,往往有多個方法的許多if語句需要調整。
  
  以傳送帶的門為例,考慮其狀態變化過程為:傳送帶的門由單個按鈕控制,并且假設初始時處于關閉狀態。按一下按鈕門開始打開,假如在門完全打開之前再次按下按鈕,門開始關閉。一旦門完全打開,它將在2秒延時之后自動開始關閉過程。要禁止門自動關閉,可以在門打開之后按一下按鈕。圖1描述了傳送門的狀態變化情況。它是一個UML狀態機(State Machine),其中click表示按下按鈕的動作。顯然,與純文字描述相比UML狀態機圖示更加直觀易懂。
  
  按照常規的設計思路(不使用State設計模式),在模擬傳送帶工作過程的軟件中,可以使用一個Door1對象代表傳送門(如圖2所示),狀態改變事件由傳送帶軟件發送給Door1對象。
   在Java中應用State設計模式(圖一)
  圖1 UML狀態機
   在Java中應用State設計模式(圖二)
  圖2 狀態改變事件發送給Door1對象
  Door1類從Observable派生,這樣客戶程序(例如一個GUI程序)就能夠方便地了解傳送門狀態。Door1類首先定義傳送門可能處于的狀態,代碼如下:
  
  public class Door1 extends Observable {
  public static final int CLOSED  = 1;
  public static final int OPENING = 2;
  public static final int OPEN   = 3;
  public static final int CLOSING = 4;
  public static final int STAYOPEN = 5;
  PRivate int state = CLOSED;
  //...
  }
  status()方法返回傳送門狀態的文字描述,如下所示:
  
  public String status() {
  switch (state) {
    case OPENING :
      return "正在打開";
    case OPEN :
      //...
    default :
      return "已關閉";
  }
  }
  當用戶點擊傳送帶的按鈕時,傳送帶程序調用Door1對象的click()方法。click()方法模擬圖1所示的狀態裝換過程:
  
  public void click() {
  if (state == CLOSED) {
    setState(OPENING);
  }
  else if (state == OPENING state == STAYOPEN) {
    setState(CLOSING);
  }
  else if (state == OPEN) {
    setState(STAYOPEN);
  }
  else if (state == CLOSING) {
    setState(OPENING);
  }
  }
  Door1類的setState()方法向觀察者通知傳送門狀態改變事件,代碼如下:
  
  private void setState(int state) {
  this.state = state;
  setChanged();
  notifyObservers();
  }
  用State模式改造
  Door1類的代碼比較復雜,整個類到處都用到了狀態變量。假如要比較圖1的狀態機和Door1類的各個狀態變換方法,將是非常困難的,click()方法尤其如此。那么,怎樣在這個例子中應用State模式呢?首先要把傳送門的各種狀態分別定義成類,如圖3所示。圖3能夠更好地與圖1的狀態機對應。更改后的類設計中,Door2包含了狀態機的上下文信息。所謂上下文信息,就是描述環境和一系列其它對象相關的信息。就本例而言,State利用一個上下文對象記錄了傳送門的當前狀態是DoorState類的哪一個實例。
  在Java中應用State設計模式(圖三)
  圖3 傳送門各個狀態
  DoorState類的構造函數要求提供一個Door2對象,DoorState的子類利用該對象傳達狀態變更信息。在這種設計方案中,DoorState的子類通過一個Door2類型的屬性綁定到特定的傳送門(Door2)對象,因而要求一個DoorState對象只被一個Door2對象引用。同時Door類要把它的狀態信息定義成局部變量,代碼如下:
  
  public class Door2 extends Observable {
  public final DoorState CLOSED  = new DoorClosed(this);
  // 按照類似方式定義DoorState類型的
  // OPENING、OPEN、CLOSING、STAYOPEN對象(略)
  private DoorState state = CLOSED;
  // ...
  }
  DoorState類是一個抽象類,由子類實現其click()方法。在狀態機中,每一個狀態均有相應的“按下按鈕”操作。修改后的設計中每一個描述狀態的類也有一個click()方法,兩者是一致的。DoorState類處理了其它可能的變換,所以DoorState的子類可以忽略無關的事件,代碼如下:
  
  public abstract class DoorState {
  protected Door2 door;
  public DoorState(Door2 door) {
    this.door = door;
  }
  public abstract void click();
  public String status() {
    String s = getClass().getName();
    return s.substring(s.lastIndexOf('.') + 1);
  }
   public void complete() { }
   public void timeout() { }
  }
  由上可以看到,現在的status()方法要比修改設計方案之前的status()方法簡單多了。新status()方法返回的結果與修改前版本的結果略有不同,它的狀態信息從類的名稱獲得。假如要返回修改設計方案之前的信息,只需把這些狀態信息分別記錄到DoorState的各個子類中,然后在這個status()方法中直接提取即可。
  
  新的設計方案中,傳送門對象(Door2)從傳送帶接收狀態改變信息的這一角色仍未改變。但現在Door2對象只需把這些狀態改變信息直接傳遞給當前的狀態對象就可以了,代碼如下:
  
  public class Door2 extends Observable {
  // ... 聲明變量
  protected void setState(DoorState state) {
    this.state = state;
    setChanged();
    notifyObservers();
  }
  public void click() {
    state.click();
  }
  // complete()、status()、timeout()都直接
  // 調用state的相應方法即可(略)
  }
  這里的click()、complete()、status()和timeout()方法體現了java類多態性的應用。所有這些方法都起著判定和選擇動作的作用,即是雖然每一個方法的代碼是不含if判定邏輯的,但實際運行時被調用的狀態對象卻不斷變化。在調用click()時會發生哪些事情呢?按照多態性規則,答案依靠于當時傳送門的狀態。修改后的代碼有效地擔負起了根據狀態執行不同動作的任務,但由于利用了多態性,它變得更加簡單了。
  
  Door2類中的setState()方法現在由DoorState的子類調用。這些DoorState的子類與圖1狀態機中的相應實體很相似,例如,狀態機中Open狀態包含Timeout和Click,DoorOpen類則包含兩個對應的方法timeout()和click()。DoorOpen類的代碼如下:
  
  public class DoorOpen extends DoorState {
  public DoorOpen(Door2 door) {
    super(door);
  }
  public void click() {
    door.setState(door.STAYOPEN);
  }
  public void timeout() {
    door.setState(door.CLOSING);
  }
  }
  從上面可以看到,利用State設計模式之后,代碼變得更簡單了。不過,細心的讀者或許已經注重到,Door2類用到的“常量”實際上是變量,這給人一種不規范的感覺。假設現在要把這些狀態常量移到_DoorConstant接口,這就需要從DoorState類消除Door2實例變量。修改辦法是:重新定義DoorState類中的click()、complete()和timeout()變換方法,把一個Door2對象以參數的形式傳遞給它們。按照這種設計方法,Door2對象調用狀態變換方法,例如click()時,將采用state.click(this)的形式。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久91香蕉国产| 亚洲999一在线观看www| 92看片淫黄大片看国产片| 欧美日本啪啪无遮挡网站| 2018国产精品视频| 国产视频精品一区二区三区| 日韩成人在线视频观看| 97视频网站入口| 国产精品入口夜色视频大尺度| 成人乱色短篇合集| 91精品国产色综合久久不卡98口| 亚洲全黄一级网站| 久久精视频免费在线久久完整在线看| 欧美极品在线视频| 国产色综合天天综合网| 欧美性受xxxx黑人猛交| 成人妇女淫片aaaa视频| 国产精品亚洲精品| 成人性生交xxxxx网站| 欧美激情在线观看视频| 日韩av一区在线| 欧美xxxx18国产| 精品福利免费观看| 亚洲男人天堂2023| 亚洲一区二区三区视频| 国产99视频在线观看| 欧美激情网友自拍| 国产成人拍精品视频午夜网站| 午夜精品久久久久久久99热浪潮| 国产中文欧美精品| 91精品久久久久久综合乱菊| 一本色道久久综合亚洲精品小说| 91久久久久久| 色伦专区97中文字幕| 日韩精品视频在线| 欧美一级电影免费在线观看| 亚洲人成亚洲人成在线观看| 日韩欧美成人免费视频| 91国产中文字幕| 久久亚洲精品网站| 国产成人精品日本亚洲| 精品久久中文字幕| 国产精品第8页| 色青青草原桃花久久综合| 国产日韩av高清| 国产精品视频在线播放| 国产美女高潮久久白浆| 日本一区二区三区在线播放| 2019中文字幕在线免费观看| 韩国19禁主播vip福利视频| 夜夜嗨av一区二区三区四区| 成人97在线观看视频| 国产精品入口夜色视频大尺度| 欧美日韩一区二区在线| 91地址最新发布| 久青草国产97香蕉在线视频| 久久久久久噜噜噜久久久精品| 久久国产精品电影| 国产精品福利久久久| 成人亚洲欧美一区二区三区| 日韩精品有码在线观看| 57pao国产精品一区| 欧美日韩国产成人在线观看| 精品国产欧美一区二区三区成人| 欧美日韩一区二区三区| 亚洲人成网7777777国产| 国产一区二区三区三区在线观看| 欧美成人免费视频| 国产欧美精品久久久| 午夜精品福利电影| 日韩欧美极品在线观看| 亚洲精品影视在线观看| 北条麻妃99精品青青久久| 日韩欧美视频一区二区三区| 麻豆乱码国产一区二区三区| 日韩在线欧美在线国产在线| 欧美另类精品xxxx孕妇| 一区国产精品视频| 亚洲成人aaa| 国产精品亚洲综合天堂夜夜| 久久久精品中文字幕| 成人激情在线观看| 亚洲免费高清视频| 韩国三级日本三级少妇99| 亚洲香蕉成视频在线观看| 精品国产乱码久久久久酒店| 综合欧美国产视频二区| 久久精品国产成人精品| 国产精品视频久久久| 日本aⅴ大伊香蕉精品视频| 国产一区二区三区日韩欧美| 久久精品国产亚洲精品| 国产视频丨精品|在线观看| 精品无人区乱码1区2区3区在线| 成人免费激情视频| 91久久久久久久| 亚洲美女黄色片| 国产成人中文字幕| 成人午夜在线观看| 国产精品一区二区久久久久| 亚洲国产成人精品电影| 日韩在线观看你懂的| 在线成人一区二区| 精品视频在线播放| 中文国产成人精品久久一| 欧美亚洲国产日本| 久久91亚洲精品中文字幕奶水| 久久久久久久久综合| 国内精品久久久久久久| 免费av在线一区| 日韩一区二区在线视频| 日韩美女av在线免费观看| 欧美激情小视频| 日韩av在线网页| 91免费看片在线| 国产精品一区二区久久精品| 国产精品99久久久久久白浆小说| 欧美美女18p| 久久国产精品久久国产精品| 少妇精69xxtheporn| 日韩激情av在线免费观看| 亚洲天堂色网站| 国产精品高清在线| 91久久精品在线| 亚洲精品中文字| 98精品国产高清在线xxxx天堂| 日韩一区二区精品视频| 国产欧美va欧美va香蕉在| 精品偷拍各种wc美女嘘嘘| 国产999在线| 日韩av中文字幕在线免费观看| 一本色道久久88精品综合| 国内精品模特av私拍在线观看| 精品久久久精品| 精品成人国产在线观看男人呻吟| 91老司机在线| 久久亚洲综合国产精品99麻豆精品福利| 欧美精品一二区| 亚洲男人天堂网站| 久久亚洲精品中文字幕冲田杏梨| 欧美亚洲在线视频| 国产精品一二区| 91av福利视频| 亚洲变态欧美另类捆绑| 日韩中文第一页| 国产精品福利网| 亚洲福利视频久久| 色黄久久久久久| 精品视频久久久久久久| 日韩在线观看免费全| 精品国产999| 亚洲人成电影在线| 中文字幕久久久av一区| 日韩在线观看免费网站| 国产精品高精视频免费| 欧美激情视频给我| 欧美黑人性视频| 久久在线观看视频| 成人性生交大片免费看视频直播| 亚洲高清久久网| 亚洲aⅴ男人的天堂在线观看| 精品视频一区在线视频| 91精品视频免费看| 久久伊人精品一区二区三区|