状态模式
引言
状态模式属于对象创建型模式,其意图是允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了他的类。比较常见的例子是在一个表示网络连接的 类TCPConnection,一个TCPConnection对象的状态处于若干不同的状态之一:连接已经建立(Established),正在监听, 连接已经关闭(closed)。当一个TCPConnection对象收到其他对象的请求时,他根据自身的状态作出不同的反应。例如:一个Open请求的 结果依赖于该连接已关闭还是连接已建立状态。State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。这一种模式的关键思想 是引入了一个称为TCPState的抽象类表示网络的连接状态,TCPState类为各种表示不同的操作状态的字类声明了一个公共接口。TCPState 的子类实现与特定的状态相关的行为。例如,TCPEstablished和TCPClosed类分别实现了特定于TCPConnection的连接已建立 状态和连接已关闭状态的行为。
定义和结构
Context(环境,具有状态的类)定义客户感兴趣的类。
A. 实例化所有状态,并记录当前状态
B. 把自己作为参数,传递给具体状态类
C. 对外暴露的所有行为接口,都以当前状态实现即可。
public class Car { private State curState;
public State getCurState() { return curState; }
public void setCurState(State curState) { this.curState = curState; } public Car() { curState = new HighSpeedState(this); } public void stop() { curState.stopCar(); } } |
State
定义一个接口以封装与Context的一个特定状态相关的行为。
定义状态相关的所有接口
public interface State { public void stopCar(); } |
ConcreteState Subclasses(具体状态子类)
每一个子类实现一个与Context的状态相关的行为。
实现所有行为,并设定状态改变。
public class HighSpeedState implements State { private Car car; public HighSpeedState(Car car) { this.car = car; } @Override public void stopCar() { // TODO Auto-generated method stub System.out.println("高速刹车,降档"); car.setCurState(new MediumSpeedState(car)); car.getCurState().stopCar(); } } |
public class LowSpeedState implements State {
private Car car; public LowSpeedState(Car car) { this.car = car; } @Override public void stopCar() { // TODO Auto-generated method stub System.out.println("挂空档,停车"); } } |
public class MediumSpeedState implements State { private Car car; public MediumSpeedState(Car car) { this.car = car; } @Override public void stopCar() { // TODO Auto-generated method stub System.out.println("刹车,降档,挂空档"); car.setCurState(new LowSpeedState(car)); car.getCurState().stopCar(); } } |
客户端
public class MyTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Car car=new Car(); car.stop(); } } |
他们的协作关系是:
- Context将于状态相关的请求委托给当前的ConcreteState对象处理。
- Context可将自身作为一个参数传递给处理该请求的状态对象,这使得状态对象在必要的时候可访问Context。
- Context是客户使用的主要接口,客户可用状态对象来配置一个Context,一旦一个Context配置完毕,他的客户不再需要直接与状态对象打交道。
- Context或者ConcreteState子类都可以决定哪个状态是另外那个状态的后继者,以及是在何种条件下进行状态转换。
总结
前提条件
使用状态模式的对象要具有不同的状态属性,切该对象有一系列动作会引起状态改变。
适用情况
1) 一个对象的具体行为取决于它的当前状态, 也就是说它必须在运行时刻根据状态来确定它的行为,且行为的变化会引起状态的改变。
2) 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。