设计模式源码git地址:design-pattern-src: 设计模式源码 (gitee.com)

  1. 定义
  2. 优点
  3. 角色
  4. 场景举例
  5. 总结

定义

将复杂的逻辑判断提取到不同的状态对象中,允许内部状态发生改变时改变其行为

优点

结构清晰,满足单一职责,减少对象的相互依赖,易于程序扩展

角色

上下文(Context):它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。

抽象状态(State):定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。

具体状态(Concrete State):实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。

场景举例

线程生命周期举例

img

如图,存在5种状态,在每个状态获得一定条件之后会转换为其他状态

如果用传统的方式实现,if/switch利用现在的状态来做这个状态下的行为

伪代码实现

1
2
3
4
5
6
7
8
9
if (o instanceof InitialState) {
//新建状态调用
} else if (o instanceof Runnable) {
//就绪状态调用
} else if (o instanceof Running) {
//运行状态调用
} else if (o instanceof Blocked) {
//阻塞状态调用
}

状态模式实现

uml类图

img

调用类

1
2
3
4
5
6
7
8
9
//上下文环境创建
Context context = new Context();
//不需要用if判断,会根据自身类型调用不同的方法
context.start();
context.getCPU();
context.suspend();
context.resume();
context.getCPU();
context.stop();

输出

1
2
3
4
5
6
7
当前线程处于:新建状态
调用start方法开始启动一个线程-->当前线程处于:就绪状态
获得CPU时间片-->当前线程处于:运行状态
阻塞条件达成-->当前线程处于:阻塞状态
阻塞解决当前线程处于:就绪状态
获得CPU时间片-->当前线程处于:运行状态
线程执行完毕-->当前线程处于:死亡状态

抽象状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public abstract class State {
private static final Exception NotSupportException = new RuntimeException("不能直接使用超类提供的方法");
//默认实现
//启动
public void start(Context context) throws Exception{
throw NotSupportException;
}
//获取时间片
public void getCPU(Context context) throws Exception{
throw NotSupportException;
}
//进行阻塞
public void suspend(Context context) throws Exception{
throw NotSupportException;
}
//进行停止
public void stop(Context context) throws Exception{
throw NotSupportException;
}
//阻塞恢复
public void resume(Context context) throws Exception{
throw NotSupportException;
}
}

具体状态(5种)

1
2
3
4
5
6
7
8
9
10
11
public class InitialState extends State{
public InitialState() {
System.out.println("当前线程处于:新建状态");
}
@Override
public void start(Context context) {
System.out.print("调用start方法开始启动一个线程-->");
context.setState(new Runnable());
}
}
//其余实现类请查看git地址

上下文环境

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
public class Context {
private State state;
Context() {
state = new InitialState();
}
//set、get
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
//启动
public void start() throws Exception{
state.start(this);
}
//获取时间片
public void getCPU() throws Exception{
state.getCPU(this);
}
//进行阻塞
public void suspend() throws Exception{
state.suspend(this);
}
//进行停止
public void stop() throws Exception{
state.stop(this);
}
//阻塞恢复
public void resume() throws Exception{
state.resume(this);
}
}

总结

最大的好处可以看到消除了if-else的写法,让整个程序更易于扩展