状态模式(State Pattern)又称为状态对象模式,该模式允许一个对象在其内部状态改变时改变其行为。
定义:
- 当一个对象内部状态改变时允许改变行为,这个对象看起来像改变了其类型。
- 状态模式的核心是封装,状态的变更引起行为的变动,从外部看来就好像该对象对应的类发生改变一样。
状态模式的类图如下所示。
状态械涉及以下3个角色:
- 抽象状态(State)角色:封装环境对象的一个特定状态所对应的行为。
- 具体状态角色:实现环境状态所对应的行为。
- 环境角色:该角色定义客户端需要的接口,并负责具体状态的切换。它会保留一个具体状态类的实例,该实例给出环境对象的现有状态。
State.java
// 抽象角色 public abstract class State { // 定义一个环境角色 protected Context context; // 设置环境 public void setContext(Context context) { this.context = context; } // 抽象行为 public abstract void handle(); }
Context.java
// 环境角色 public class Context { // 定义状态 public static State STATE1 = new ConcreteState1(); public static State STATE2 = new ConcreteState2(); // 当前状态 private State currentState; // 获取当前状态 public State getCurrentState() { return currentState; } // 设置当前状态 public void setCurrentState(State currentState) { this.currentState = currentState; // 设置环境中的状态 currentState.setContext(this); } // 行为委托 public void handle1() { // 切换到状态1 this.setCurrentState(STATE1); this.currentState.handle(); } public void handle2() { // 切换到状态1 this.setCurrentState(STATE2); this.currentState.handle(); } }
ConcreteState1.java
// 具体状态1 public class ConcreteState1 extends State { // 状态1的行为逻辑处理 @Override public void handle() { System.out.println("行为1的逻辑处理"); } }
ConcreteState2.java
// 具体状态2 public class ConcreteState2 extends State { // 状态2的行为逻辑处理 @Override public void handle() { System.out.println("行为2的逻辑处理"); } }
Client.java
// 应用程序 public class Client { public static void main(String[] args) { // 定义环境角色 Context context = new Context(); // 执行行为 context.handle1(); context.handle2(); } }
优点:
- 结构清晰。
- 遵循设计原则。
- 封装性非常好。
缺点:
- 子类太多,不易管理。
应用场景:
- 对象的行为依赖于它所处的状态,即行为随状态改变而改变的场景。
- 对象在某个方法里依赖于一重或多重条件分支语句,此时可以使用状态模式将分支中的每一个分支都包装到一个单独的类中,使得这些条件分支能够以类的方式单独存在和演化。如此,维护这些独立的类就不再影响到系统的其他部分。
摘自:
青岛东合信息技术有限公司 . 设计模式(Java版) . 电子工业出版社,2012,170-172.