Java设计模式(十二)—— 状态模式
状态模式定义如下:允许一个对象在其内部状态改变时改变它的行为,使对象看起来似乎修改了它的类。
适合状态模式的情景如下:
- 对象的行为依赖于它的状态,并且它必须在运行时根据状态改变它的行为。
- 需要编写大量的条件分支语句来决定一个操作的行为,而且这些条件恰好表示对象的一种状态。
一、问题的提出
生活中有一类事物,有N种状态,在每种状态下均有不同的特征。在一定的条件下,状态间可以相互转化。例如水有固液气三态。
二、状态模式
事物有N个状态,且维护状态变化。从这句话得出重要结论:
- 状态类有共同的父接口,N个不同的状态实现类
- 事物类中包含状态类父接口成员变量声明,用以反映语义:事物有N个状态
- 事物类中一定有方法选择分支,判断事物当前处于何种状态
状态模式必须完成下面内容的编制:
- State:状态接口,封装特定状态所对应的行为
- ConcreteState:具体实现状态处理的类
- Context:事物类,也称上下文类,通常用来定义多态状态接口 ,同时维护一个来具体处理当前状态的实例对象。
(1)定义状态抽象接口IState
public interface IState {public void goState();
}
(2)定义状态实现类
public class ConcreteStateA implements IState{@Overridepublic void goState() {System.out.println("这是状态A");}
}public class ConcreteStateB implements IState{@Overridepublic void goState() {System.out.println("这是状态B");}
}
(3)定义状态上下文维护类
public class Context {private IState state;public void setState(IState state) {this.state = state;}public void manage() {state.goState();}
}
三、实例
以水的状态为例:
(1)定义水状态抽象接口
public interface IWaterState {void handle();
}
(2)定义三个状态实现类
public class LiquidState implements IWaterState {@Overridepublic void handle() {System.out.println("水处于液态");}
}public class SolidState implements IWaterState {@Overridepublic void handle() {System.out.println("水处于固态");}
}public class GasState implements IWaterState {@Overridepublic void handle() {System.out.println("水处于气态");}
}
(3)定义上下文类
// 定义上下文类
public class Water {private IWaterState state;public void setState(IWaterState state) {this.state = state;}public void handle() {state.handle();}
}
(4)测试
public class Test {public static void main(String[] args) {Water water = new Water();// 将水的初始状态设置为液态water.setState(new LiquidState());water.handle();// 将水的状态设置为固态water.setState(new SolidState());water.handle();// 将水的状态设置为气态water.setState(new GasState());water.handle();}
}
结果:
水处于液态
水处于固态
水处于气态
在这个例子中,我们定义了一个状态接口(State),并实现了具体的状态类(LiquidState、SolidState和GasState)。在上下文类Water中,我们将状态设置为不同的值,然后调用handle方法来执行状态所对应的操作。