意图
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
结构
- Context(上下文)定义客户感兴趣的接口;维护一个ConcreteState子类的实例,这个实例定义当前状态。
- State(状态)定义一个接口以封装与Context的一个特定状态相关的行为。
- ConcreteState(具体状态子类)每个子类实现与Context的一个状态相关的行为。
- Handle是一个代表处理当前状态的动作或方法的命名。在状态模式中,每个具体状态子类都会实现自己的 handle 方法,用来定义该状态下的具体行为或逻辑。当上下文调用 handle 方法时,实际执行的是当前状态对应的具体状态子类中的 handle 方法。
适用性
- 一个对象的行为决定于它的状态,并且它必须在运行时刻根据状态改变它的行为。
- 一个操作中含有庞大的多分支条件语句,且这些分支依赖于该对象的状态。这个状态常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得开发者可以根据对象自身的情况将对象的状态作为一个对象,这个对象可以不依赖于其他对象独立变化。
代码示例
// 状态接口
interface State {
void handle();
}
// 具体状态子类A
class ConcreteStateA implements State {
@Override
public void handle() {
System.out.println("Handling state A");
}
}
// 具体状态子类B
class ConcreteStateB implements State {
@Override
public void handle() {
System.out.println("Handling state B");
}
}
// 上下文类
class Context {
private State currentState;
public Context() {
// 初始状态为A
currentState = new ConcreteStateA();
}
public void setState(State state) {
this.currentState = state;
}
public void request() {
currentState.handle();
}
}
// 测试
public class StatePatternExample {
public static void main(String[] args) {
Context context = new Context();
// 初始状态为A
context.request();
// 改变状态为B
context.setState(new ConcreteStateB());
context.request();
}
}
在这个示例中,State接口定义了状态的行为,ConcreteStateA和ConcreteStateB是具体状态子类,分别实现了不同状态下的行为。Context类维护了一个当前状态的实例,根据当前状态来调用相应的行为。在测试中,创建了一个Context对象并初始化为状态A,然后改变状态为B并调用请求方法,观察输出结果。