0
点赞
收藏
分享

微信扫一扫

在Java中应用State设计模式

在Java中应用State设计模式_sed

对象的状态由各个属性的当前值构成。当我们调用某个对象的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();
}


举报

相关推荐

0 条评论