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()方法向观察者通知传送门状态改变事件,代码如下:
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()方法中直接提取即可。