Design Pattern: State 模式
如果您不了解TCP的连线方式,在看
?
Main.javapublic class Main { public static void main(String[] args) { State state = new State(); state.switchFire(); state.switchFire(); state.switchFire(); state.switchFire(); } }
这个方法很简单,每个人都会,但如果您的状态变化并不是流水式的变化,而是像TCP连线状态一样,会是一个网络图的时候,用 if...else或switch来写的话,您的程式就会乱的不像话了;来考虑如何让物件控制自己的状态转换与所应表现的行为,这个程式可以这样改写:
public interface IState { public void switchFire(FireSwitch sw); } ?
OffStatepublic class OffState implements IState { public void switchFire(FireSwitch sw) { sw.setState(new SmallState()); System.out.println( "small fire" ); } } ?
SmallState.javapublic class SmallState implements IState { public void switchFire(FireSwitch sw) { sw.setState(new MediumState()); System.out.println( "medium fire" ); } } ?
MediumState.javapublic class MediumState implements IState { public void switchFire(FireSwitch sw) { sw.setState(new LargeState()); System.out.println( "large fire" ); } } ?
LargeState.javapublic class LargeState implements IState { public void switchFire(FireSwitch sw) { sw.setState(new OffState()); System.out.println( "off fire" ); } } ?
FireSwitch.javapublic class FireSwitch { private State current; public FireSwitch() { current = new OffState(); } public void setState(State s) { current = s; } public void switchFire() { current.switchFire(this); }} ?
Main.javapublic class Main { public static void main(String[] args) { FireSwitch fireSwitch = new FireSwitch(); fireSwitch.switchFire(); fireSwitch.switchFire(); fireSwitch.switchFire(); fireSwitch.switchFire(); } }
程式执行结果与上一个例子是一样的,但这次并没有用流程控制来进行状态转换,而由物件自行控制自己的状态,与必须表现的行为,这个方式就是State 模式,将这个例子的 UML 类别结构画出就如下所示:
IState.java
public interface IState { public void switchClockWise(FireSwitch sw); public void switchCountClock(FireSwitch sw); } ?
OffState.javapublic class OffState implements IState { public void switchClockWise(FireSwitch sw) { sw.setState(new SmallState()); System.out.println("small fire"); } public void switchCountClock(FireSwitch sw) { sw.setState(new LargeState()); System.out.println("large fire"); } } ?
SmallState.javapublic class SmallState implements IState { public void switchClockWise(FireSwitch sw) { sw.setState(new MediumState()); System.out.println("medium fire"); } public void switchCountClock(FireSwitch sw) { sw.setState(new OffState()); System.out.println("off fire"); } } ?
MediumState.javapublic class MediumState implements IState { public void switchClockWise(FireSwitch sw) { sw.setState(new LargeState()); System.out.println("large fire"); } public void switchCountClock(FireSwitch sw) { sw.setState(new SmallState()); System.out.println("small fire"); } } ?
LargeState.javapublic class LargeState implements State { public void switchClockWise(FireSwitch sw) { sw.setState(new OffState()); System.out.println("off fire"); } public void switchCountClock(FireSwitch sw) { sw.setState(new MediumState()); System.out.println("medium fire"); } } ?
FireSwitch.javapublic class FireSwitch { private State current; public FireSwitch() { current = new OffState(); } public void setState(State s) { current = s; } public void switchClockWise() { current.switchClockWise(this); } public void switchCountClock() { current.switchCountClock(this); } } ?
Main.javapublic class Main { public static void main(String[] args) { FireSwitch fireSwitch = new FireSwitch(); fireSwitch.switchClockWise(); fireSwitch.switchClockWise(); fireSwitch.switchClockWise(); fireSwitch.switchClockWise(); System.out.println(); fireSwitch.switchCountClock(); fireSwitch.switchCountClock(); fireSwitch.switchCountClock(); fireSwitch.switchCountClock(); } }
接下来您可以任意的转动开关了,无论是顺时针转动或是逆时针转动,状态的转换都由物件自己来表现,这是双向状态转换下的例子,如果一个状态可能转换至三个以上的状态,使用State模式就更可以看出它的好处了,就像Gof的TCP连线例子一样,如果您了解TCP连线,可以看看原书是如何实现TCP连线之间的状态转换的。