程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 在Java中應用State設計模式

在Java中應用State設計模式

編輯:關於JAVA

對象的狀態由各個屬性的當前值構成。當我們調用某個對象的setXXX()方法時,通常表示修改它的XXX屬性。另外,對象在執行方法時,也可能修改自己的狀態。在某些情形下,例如建立事務或機器模型時,對象的狀態可能是決定其行為的關鍵因素,依賴於狀態的代碼邏輯可能遍布於類的大量方法。State模式的目標就是簡化這類代碼,把依賴於狀態的邏輯集中到一組類,每一個類代表一種不同的狀態,避免if語句嵌套過深或過於復雜,轉而依賴於多態性來調用不同的方法。

狀態模型

如果對象的狀態信息很關鍵,對象會擁有一些變量來指示如何根據狀態做出相應的動作。這些變量大量地散布於復雜的多層嵌套if語句中,來描述對象如何響應可能出現的事件。用這種方式建立對象模型的最大缺點在於if語句可能變得相當復雜一旦要修改對象的狀態模型,往往有多個方法的許多if語句需要調整。

以傳送帶的門為例,考慮其狀態變化過程為:傳送帶的門由單個按鈕控制,並且假設初始時處於關閉狀態。按一下按鈕門開始打開,如果在門完全打開之前再次按下按鈕,門開始關閉。一旦門完全打開,它將在2秒延時之後自動開始關閉過程。要禁止門自動關閉,可以在門打開之後按一下按鈕。圖1描述了傳送門的狀態變化情況。它是一個UML狀態機(State Machine),其中click表示按下按鈕的動作。顯然,與純文字描述相比UML狀態機圖示更加直觀易懂。

按照常規的設計思路(不使用State設計模式),在模擬傳送帶工作過程的軟件中,可以使用一個Door1對象代表傳送門(如圖2所示),狀態改變事件由傳送帶軟件發送給Door1對象。

圖1 UML狀態機

圖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();
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved