状态模式(State Pattern)

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

核心思想

将状态相关的逻辑从主对象(上下文)中分离出来,每个状态作为一个独立的类。

结构组成

  • 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(); // 初始状态为 New
}

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(); // New -> Ready
process.schedule(); // Ready -> Running
process.ioWait(); // RUnning -> Waiting
process.eventComplete(); // Waiting -> Ready
process.schedule(); // Ready -> Running
process.exit(); // Running -> Terminated

总结

通过状态模式,我们实现了:

  • 每个状态的行为解耦,易于维护和扩展。
  • 避免了大量的条件判断语句。
  • 可以轻松扩展更多状态(如挂起态Suspend、阻塞挂起态Blocked/Suspend等)