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