允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
核心思想
将状态相关的逻辑从主对象(上下文)中分离出来,每个状态作为一个独立的类。
结构组成
Context
: 维护一个对当前状态的引用,并定义客户感兴趣的接口。
State
: 定义与状态相关的行为。
ConcreteState
类: 实现State
接口中定义的行为,并可能根据状态的变化修改Context
的状态。
应用场景
- 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变其行为。
- 当业务逻辑中存在大量与状态相关的条件分支,且这些分支随着状态变化而变化。
真实案例
计算机进程在其生命周期有“三态模型”和“五态模型”。
先定义状态接口ProcessState
1 2 3 4 5 6 7 8
| public interface ProcessState { void schedule(ProcessContext context); void ioWait(ProcessContext context); void interrupt(ProcessContext context); void exit(ProcessContext context); void eventComplete(ProcessContext context); String getStatus(); }
|
具体状态类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| public class NewState implements ProcessState { @Override public void schedule(ProcessContext context) { System.out.println("Admitting process to Ready state"); context.setState(new ReadyState()); }
@Override public void exit(ProcessContext context) { System.out.println("Process terminated from New state"); context.setState(new TerminatedState()); }
@Override public void ioWait(ProcessContext context) {} @Override public void interrupt(ProcessContext context) {} @Override public void eventComplete(ProcessContext context) {}
@Override public String getStatus() { return "New"; } }
public class ReadyState implements ProcessState { @Override public void schedule(ProcessContext context) { System.out.println("Process is now Running"); context.setState(new RunningState()); }
@Override public void ioWait(ProcessContext context) {} @Override public void interrupt(ProcessContext context) {} @Override public void exit(ProcessContext context) {} @Override public void eventComplete(ProcessContext context) {}
@Override public String getStatus() { return "Ready"; } }
public class RunningState implements ProcessState { @Override public void ioWait(ProcessContext context) { System.out.println("Process is waiting for I/O"); context.setState(new WaitingState()); }
@Override public void interrupt(ProcessContext context) { System.out.println("Process interrupted, back to Ready"); context.setState(new ReadyState()); }
@Override public void exit(ProcessContext context) { System.out.println("Process exited normally"); context.setState(new TerminatedState()); }
@Override public void schedule(ProcessContext context) {} @Override public void eventComplete(ProcessContext context) {}
@Override public String getStatus() { return "Running"; } }
public class WaitingState implements ProcessState { @Override public void eventComplete(ProcessContext context) { System.out.println("I/O complete, back to Ready"); context.setState(new ReadyState()); }
@Override public void schedule(ProcessContext context) {} @Override public void ioWait(ProcessContext context) {} @Override public void interrupt(ProcessContext context) {} @Override public void exit(ProcessContext context) {}
@Override public String getStatus() { return "Waiting"; } }
public class TerminatedState implements ProcessState { @Override public String getStatus() { return "Terminated"; }
@Override public void schedule(ProcessContext context) {} @Override public void ioWait(ProcessContext context) {} @Override public void interrupt(ProcessContext context) {} @Override public void exit(ProcessContext context) {} @Override public void eventComplete(ProcessContext context) {} }
|
上下文ProcessContext
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class ProcessContext { private ProcessState state;
public ProcessContext() { this.state = new NewState(); }
public void setState(ProcessState state) { this.state = state; System.out.println("状态切换至:" + state.getStatus()); }
public void schedule() { state.schedule(this); }
public void ioWait() { state.ioWait(this); }
public void interrupt() { state.interrupt(this); }
public void exit() { state.exit(this); }
public void eventComplete() { state.eventComplete(this); }
public String getStatus() { return state.getStatus(); } }
|
使用示例
1 2 3 4 5 6 7
| val process = ProcessContext() process.schedule(); process.schedule(); process.ioWait(); process.eventComplete(); process.schedule(); process.exit();
|
总结
通过状态模式,我们实现了:
- 每个状态的行为解耦,易于维护和扩展。
- 避免了大量的条件判断语句。
- 可以轻松扩展更多状态(如挂起态Suspend、阻塞挂起态Blocked/Suspend等)