状态模式State

【摘要】状态模式State,即允许一个对象在其内部状态改变时改变它的行为。简单来说就是根据状态决定行为。

前言

工作一年多来,公司项目中一直有一个烫手的系统功能部分,那就是关于电表设备的密钥变更。其实主要难在它复杂的变更流程以及设备回复的未知,复杂的流程主要就是产品经理画的流程图以及触发条件的参数构造和本次执行变更的众多数据,光流程图就打印了我十好几张A3纸。设备回复的未知体现在真实设备的匮乏,很难凑齐一套完整的组网集中器和下挂表去真实模拟。总之这项功能完成起来很不容易。为什么在这里提到这件事情,主要是因为这部分功能的实现就是基于状态模式。欲知后续,且慢慢看来。

状态模式(State Pattern)

状态模式State,即允许一个对象在其内部状态改变时改变它的行为。简单来说就是根据状态决定行为。

应用场景

你女朋友的哭笑叨唠

举例一个简单的场景,说是我们需要描述你女朋友在不同心情下不同的行为,假设说你女朋友在开心的时候会笑,在难过的时候会哭等等。根据这个场景的描述,我们很容易就可以写出下面的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.aiz.dp.state.v1;
public class MM {
String name;
private enum MMState{HAPPY,SAD}
MMState state;

public void smile(){
//switch case
}

public void cry(){
//switch case
}

public void say(){
//switch case
}

}

这个时候我们想要增加你女朋友在紧张的时候怎么说话,那么我们需要怎么修改代码?考虑过后,我们需要添加一个方法,同时需要在每个方法都增加case代码。

但是,要是使用状态模式,我们就会写出下面这样的代码。
首选还是先给你创建一个女朋友。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.aiz.dp.state.v2;

public class MM {
String name;
MMState state;

public void smile(){
state.smile();
}

public void cry(){
state.cry();
}

public void say(){
state.say();
}

}

创建一个状态类。

1
2
3
4
5
6
7
package com.aiz.dp.state.v2;

public abstract class MMState {
abstract void smile();
abstract void cry();
abstract void say();
}

创建不同的状态实现类,分别在不同状态实现不同的动作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.aiz.dp.state.v2;

public class MMHappyState extends MMState{

@Override
void smile() {
System.out.println("happy smile");
}

@Override
void cry() {

}

@Override
void say() {

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.aiz.dp.state.v2;

public class MMSadState extends MMState{

@Override
void smile() {

}

@Override
void cry() {
System.out.println("sad cry");
}

@Override
void say() {

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.aiz.dp.state.v2;

public class MMNervousState extends MMState{
@Override
void smile() {

}

@Override
void cry() {

}

@Override
void say() {
System.out.println("nervous");
}
}

根据上面的例子,我们可以很容易理解状态模式。类图大概如下。

我的理解是这样的如果你女朋友只是smile,cry,say这三个动作,同时它的心情是多边变的,就很适合使用状态模式来描述你女朋友的行为。不过状态模式用与不用还是根据实际情况决定。

TCPConnection案例

不过在下面这本书籍中,里面有关于状态模式很经典的例子:TCP的Connection。

让人头疼的密钥变更

公司秘密,不能外漏;等我跑路,定会带走。

有限状态机(FSM)

有限状态机Finite state machine

Java线程状态迁移图

结束语

Car的State与Action

State/Action open the door close the door run the car stop the car
Open no yes no no
Closed yes
Running
Stopped

评论