知识大全 在Java中应用State设计模式

Posted 状态

篇首语:不要为成功而努力,要为作一个有价值的人而努力。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 在Java中应用State设计模式相关的知识,希望对你有一定的参考价值。

在Java中应用State设计模式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  对象的状态由各个属性的当前值构成 当我们调用某个对象的setXXX()方法时 通常表示修改它的XXX属性 另外 对象在执行方法时 也可能修改自己的状态 在某些情形下 例如建立事务或机器模型时 对象的状态可能是决定其行为的关键因素 依赖于状态的代码逻辑可能遍布于类的大量方法 State模式的目标就是简化这类代码 把依赖于状态的逻辑集中到一组类 每一个类代表一种不同的状态 避免if语句嵌套过深或过于复杂 转而依赖于多态性来调用不同的方法   状态模型  如果对象的状态信息很关键 对象会拥有一些变量来指示如何根据状态做出相应的动作 这些变量大量地散布于复杂的多层嵌套if语句中 来描述对象如何响应可能出现的事件 用这种方式建立对象模型的最大缺点在于if语句可能变得相当复杂一旦要修改对象的状态模型 往往有多个方法的许多if语句需要调整     以传送带的门为例 考虑其状态变化过程为 传送带的门由单个按钮控制 并且假设初始时处于关闭状态 按一下按钮门开始打开 如果在门完全打开之前再次按下按钮 门开始关闭 一旦门完全打开 它将在 秒延时之后自动开始关闭过程 要禁止门自动关闭 可以在门打开之后按一下按钮 图 描述了传送门的状态变化情况 它是一个UML状态机(State Machine) 其中click表示按下按钮的动作 显然 与纯文字描述相比UML状态机图示更加直观易懂     按照常规的设计思路(不使用State设计模式) 在模拟传送带工作过程的软件中 可以使用一个Door 对象代表传送门(如图 所示) 状态改变事件由传送带软件发送给Door 对象       图 UML状态机      图 状态改变事件发送给Door 对象  Door 类从Observable派生 这样客户程序(例如一个GUI程序)就能够方便地了解传送门状态 Door 类首先定义传送门可能处于的状态 代码如下     public class Door extends Observable   public static final int CLOSED  = ;  public static final int OPENING = ;  public static final int OPEN   = ;   public static final int CLOSING = ;  public static final int STAYOPEN = ;   private int state = CLOSED;  //     status()方法返回传送门状态的文字描述 如下所示     public String status()   switch (state)     case OPENING :      return "正在打开";    case OPEN :      //     default :      return "已关闭";      当用户点击传送带的按钮时 传送带程序调用Door 对象的click()方法 click()方法模拟图 所示的状态装换过程     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);      Door 类的setState()方法向观察者通知传送门状态改变事件 代码如下     private void setState(int state)   this state = state;  setChanged();  notifyObservers();    用State模式改造  Door 类的代码比较复杂 整个类到处都用到了状态变量 如果要比较图 的状态机和Door 类的各个状态变换方法 将是非常困难的 click()方法尤其如此 那么 怎样在这个例子中应用State模式呢?首先要把传送门的各种状态分别定义成类 如图 所示 图 能够更好地与图 的状态机对应 更改后的类设计中 Door 包含了状态机的上下文信息 所谓上下文信息 就是描述环境和一系列其它对象相关的信息 就本例而言 State利用一个上下文对象记录了传送门的当前状态是DoorState类的哪一个实例      图 传送门各个状态  DoorState类的构造函数要求提供一个Door 对象 DoorState的子类利用该对象传达状态变更信息 在这种设计方案中 DoorState的子类通过一个Door 类型的属性绑定到特定的传送门(Door )对象 因而要求一个DoorState对象只被一个Door 对象引用 同时Door类要把它的状态信息定义成局部变量 代码如下     public class Door 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 Door door;  public DoorState(Door door)     this door = door;    public abstract void click();  public String status()     String s = getClass() getName();    return s substring(s lastIndexOf( ) + );     public void plete()    public void timeout()     由上可以看到 现在的status()方法要比修改设计方案之前的status()方法简单多了 新status()方法返回的结果与修改前版本的结果略有不同 它的状态信息从类的名称获得 如果要返回修改设计方案之前的信息 只需把这些状态信息分别记录到DoorState的各个子类中 然后在这个status()方法中直接提取即可     新的设计方案中 传送门对象(Door )从传送带接收状态改变信息的这一角色仍未改变 但现在Door 对象只需把这些状态改变信息直接传递给当前的状态对象就可以了 代码如下     public class Door extends Observable   // 声明变量  protected void setState(DoorState state)     this state = state;    setChanged();    notifyObservers();    public void click()     state click();    // plete() status() timeout()都直接  // 调用state的相应方法即可(略)    这里的click() plete() status()和timeout()方法体现了Java类多态性的应用 所有这些方法都起著判断和选择动作的作用 即是虽然每一个方法的代码是不含if判断逻辑的 但实际运行时被调用的状态对象却不断变化 在调用click()时会发生哪些事情呢?按照多态性规则 答案依赖于当时传送门的状态 修改后的代码有效地担负起了根据状态执行不同动作的任务 但由于利用了多态性 它变得更加简单了     Door 类中的setState()方法现在由DoorState的子类调用 这些DoorState的子类与图 状态机中的相应实体很相似 例如 状态机中Open状态包含Timeout和Click DoorOpen类则包含两个对应的方法timeout()和click() DoorOpen类的代码如下     public class DoorOpen extends DoorState   public DoorOpen(Door door)     super(door);    public void click()     door setState(door STAYOPEN);    public void timeout()     door setState(door CLOSING);      从上面可以看到 利用State设计模式之后 代码变得更简单了 不过 细心的读者或许已经注意到 Door 类用到的 常量 实际上是变量 这给人一种不规范的感觉 假设现在要把这些状态常量移到_DoorConstant接口 这就需要从DoorState类消除Door 实例变量 修改办法是 重新定义DoorState类中的click() plete()和timeout()变换方法 把一个Door 对象以参数的形式传递给它们 按照这种设计方法 Door 对象调用状态变换方法 例如click()时 将采用state click(this)的形式                  cha138/Article/program/Java/gj/201311/27535

相关参考

知识大全 java设计模式之State(对应每种状态的行为)

java设计模式之State(对应每种状态的行为)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 

知识大全 在Java中应用设计模式Singleton

在Java中应用设计模式Singleton  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  &nb

知识大全 在Java中应用设计模式之Singleton

在Java中应用设计模式之Singleton  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  基本

知识大全 该如何实践State模式

该如何实践State模式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!State模式将对象行为的变

知识大全 J2EE设计模式之State模式

J2EE设计模式之State模式  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  设计模式这个概念

知识大全 java数据库设计中的14个技巧

  下述十四个技巧是许多人在大量的数据库分析与设计实践中逐步总结出来的对于这些经验的运用读者不能生帮硬套死记硬背而要消化理解实事求是灵活掌握并逐步做到在应用中发展在发展中应用原始单据与实体之间的关系 

知识大全 高级应用 java多线程设计模式详解之一

  线程的创建和启动    java语言已经内置了多线程支持所有实现Runnable接口的类都可被启动一个新线程新线程会执行该实例的run()方法当run()方法执行完毕后线程就结束了一旦一个线程执行

知识大全 高级应用——Java动态的程序设计

高级应用——Java动态的程序设计  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  类和类的装载 

知识大全 数据压缩格式Java语言应用程序设计方法

数据压缩格式Java语言应用程序设计方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  数据压缩

知识大全 设计模式分解java(2)

  当然也可以结合工厂模式来创建AbstractSpoon实例  在Java中Prototype模式变成clone()方法的使用由于Java的纯洁的面向对象特性  使得在Java中使用设计模式变得很自