概述
- 状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题。当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式。
- 状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化,对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何种状态的对象,客户端都可以一致处理。
- 别名为状态对象(Objects for States)
- 状态模式是一种对象行为型模式。
- 学习难度:★★★☆☆
- 使用频率:★★★☆☆
概述优缺点
类图
组成角色
- 环境角色(Context)
- 状态角色(State)
- 具体状态角色(ConcreteState)
Code Example
环境角色(Context)
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void nextStep() {
if (this.state != null) {
this.state.nextStep(this);
}
}
public void lastStep() {
if (this.state != null) {
this.state.lastStep(this);
}
}
public State getState() {
return this.state;
}
}
状态角色(State)
public interface State {
public void lastStep(Context ctx);
public void nextStep(Context ctx);
}
具体状态角色(ConcreteState)
public class FirstState implements State {
public void lastStep(Context ctx) {
ctx.setState(null);
}
public void nextStep(Context ctx) {
ctx.setState(new SecondState());
}
@Override
public String toString() {
return "First State";
}
}
public class SecondState implements State {
public void lastStep(Context ctx) {
ctx.setState(new FirstState());
}
public void nextStep(Context ctx) {
ctx.setState(new ThirdState());
}
@Override
public String toString() {
return "Second State";
}
}
public class ThirdState implements State {
public void lastStep(Context ctx) {
ctx.setState(new SecondState());
}
public void nextStep(Context ctx) {
ctx.setState(null);
}
@Override
public String toString() {
return "Third State";
}
}
客户端
public class StatePattern {
public static void main(String[] args) {
State state = new FirstState();
Context ctx = new Context(state);
for (int i = 0; i < 6; i++) {
state = ctx.getState();
System.out.print(state);
if (state == null) {
break;
}
System.out.print("->");
ctx.nextStep();
}
System.out.println("");
state = new ThirdState();
ctx = new Context(state);
for (int i = 0; i < 6; i++) {
state = ctx.getState();
System.out.print(state);
if (state == null) {
break;
}
System.out.print("->");
ctx.lastStep();
}
}
}