状态模式
# 一、概述
状态(State)模式能在一个对象的内部状态变化时改变其行为,使其看起来像是改变了自己所属的类一样。
# 1.1 解决了什么问题
状态模式主要用来解决对象需要在多种状态之间进行切换,且每种状态下的行为互不相同的问题。
如果用传统的方式处理的话就需要写一堆的 if...else...或者 swtich 语句。
# 1.2 解决方案
状态模式建议为所有可能的状态新建一个类,然后将所有状态的对应行为抽取到这些类中。
原始对象(一般被称为上下文)会保存一个指向表示当前状态的状态对象的引用,且将所有与状态相关的工作委派给该对象。如需将上下文转为另一种状态,只需要将当前活动的状态对象替换为另外一个状态的对象。
# 二、实现方式
# 2.1 角色
- Context:上下文,保存了对一个具体状态对象的引用,并将所有与状态相关的工作都委派给它。
- State:状态接口,声明特定状态的方法。
- Concrete State:自动实现特定状态的方法。
# 2.2 代码
以播放器的启动、播放和停止三个状态为为例。
定义状态接口。这个例子比较简单,实际的业务中可能比较复杂,接口中也许会有多个抽象方法,也可以使用抽象类。
public interface State {
void doAction(Context context);
}
1
2
3
2
3
定义上下文,其保存了一个 State 对象的引用。它其实是状态的保持者和切换者。
public class Context {
private State state;
public Context() {
state = null;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
定义三个状态:
public class StartState implements State {
@Override
public void doAction(Context context) {
System.out.println("Player is in start state");
context.setState(this);
}
public String toString() {
return "start state";
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
public class PlayState implements State {
@Override
public void doAction(Context context) {
System.out.println("Player is in play state");
context.setState(this);
}
public String toString() {
return "play state";
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
public class StopState implements State {
@Override
public void doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
public String toString() {
return "stop state";
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
使用示例:
public class StateTest {
public static void main(String[] args) {
Context context = new Context();
StartState startState = new StartState();
startState.doAction(context);
PlayState playState = new PlayState();
playState.doAction(context);
StopState stopState = new StopState();
stopState.doAction(context);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Player is in start state
Player is in play state
Player is in stop state
1
2
3
2
3
在真实的业务中不会在客户端中人工做状态切换,应该根据业务需求有一个完整的状态流转流程的,应当在状态流转流程中自动化切换。
# 三、源码中的应用
javax.faces.lifecycle.LifeCycle#execute() (由 FacesServlet 控制: 行为依赖于当前 JSF 生命周期的阶段 (状态))
上次更新: 2023/11/01, 03:11:44