状态模式/State
意图/适用场景:
状态模式允许一个对象在其内部状态改变的时候改变其行为,这个对象看上去就像是改变了它的类一样。
在两种情况下均可以使用状态模式:
- 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
- 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。状态模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个新的对象,这一新的对象可以不依赖于同类的其他对象而独立变化。
状态模式有下面一些效果:
- 它将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
- 它使得状态转换显式化。
- 状态对象可被共享。
UML:
参与者:
- 抽象状态(State):状态类的接口,封装了环境对象的一个特定状态所对应的行为。
- 具体状态(ConcreteState):实现某一状态所对应的行为。
- 环境(Context):保留状态类的实例,依当前所处的状态不同而更换这个实例,实现不同的行为。
要点:
什么时候创建和销毁State对象是一个值得考虑问题。有两种选择:
- 仅当需要State对象时才创建它们并随后销毁它们。
- 提前创建它们并且始终不销毁它们。
应根据State对象的数量、每一个State对象的创建成本以及系统的要求来选择。
应用实例:
考虑一个表示网络连接的类TCPConnection。一个TCPConnection对象的状态处于若干不同状态之一:连接已建立(Established)、正在监听(Listening)、连接已关闭(Closed)。当一个TCPConnection对象收到其他对象的请求时,它根据自身的当前状态作出不同的反应。例如,一个Open请求的结果依赖于该连接是处于连接已关闭状态还是连接已建立状态。
State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。
示例代码:
[java]
// Source code from file:ConcreteStateA.java
packagedesignPatterns.State;
publicclass ConcreteStateA implements State {
publicvoid operation() {
System.out.println("ConcreteStateA.operation()");
}
}
// Source code from file:ConcreteStateB.java
packagedesignPatterns.State;
publicclass ConcreteStateB implements State {
publicvoid operation() {
System.out.println("ConcreteStateB.operation()");
}
}
// Source code from file:Context.java
packagedesignPatterns.State;
publicclass Context {
privateState state = null;
privateState stateA = null;
privateState stateB = null;
publicContext() {
stateA =new ConcreteStateA();
stateB =new ConcreteStateB();
state = stateA;
}
publicvoid switchState() {
if(state == stateA)
state = stateB;
else
state = stateA;
}
publicvoid operation() {
state.operation();
}
}
// Source code from file:State.java
packagedesignPatterns.State;
publicinterface State {
publicvoid operation();
}
// Source code from file:User.java
packagedesignPatterns.State;
publicclass User {
publicstatic void main(String[] args) {
Contextc = new Context();
c.operation();
c.switchState();
c.operation();
c.switchState();
c.operation();
}
}
[/java]