目录
前言
考虑一个对象对于不同阶段,不同状态有不同的表现,如tcp连接的监听、建立和关闭。如果使用if else判断来处理将增大复杂度,甚至后续有新状态不利于代码解耦合。而State模式有利于解决这种情况。
1 定义
State(状态)模式:允许一个对象在其状态改变时改变自身行为。
2 适用性
- 一个对象的行为取决于它的状态,并且是根据它运行时状态改变它的行为。
- 一个操作有复杂的多分支条件语句,而且判断条件跟对象状态有关。
3 结构
3.1 结构图
State模式结构图如下:
3.2 参与者
- Context:环境,定义客户感兴趣的接口,维护一个_state变量,根据状态处理行为。
- State:状态,描述环境的状态,环境的行为具体是通过该接口的实现处理。
- ConcreteState:具体状态,环境目前的可能状态,定义具体的处理逻辑和转变情况。
4 应用举例
自定义一个模拟tcp状态转变实例。
4.1 State——TcpState
TcpState定义如下:
/**
* tcp状态接口
*/
public interface TcpState {
/**
* 关闭连接
*/
void close(TcpConnection tcpConnection);
/**
* 建立连接
*/
void established(TcpConnection tcpConnection);
/**
* 监听状态
*/
void listening(TcpConnection tcpConnection);
}
定义tcp状态的三个操作:监听、建立和关闭。
4.2 Context——TcpConnection
TcpConnection定义如下:
/**
* tcp模拟类,存储连接信息
*/
@Data
public class TcpConnection {
private TcpState tcpState;
public void listen() {
tcpState.listening(this);
}
public void establish() {
tcpState.established(this);
}
public void close() {
tcpState.close(this);
}
}
内部维持一个指向当前状态的指针,具体行为均由状态处理。
4.3 ConcreteState——ListeningTcpState、EstablishedTcpState和CloseTcpState
这几个状态转换情况简化为下面图:
4.3.1 ListeningTcpState
定义如下:
/**
* 监听状态类
*/
public class ListeningTcpState implements TcpState{
@Override
public void close(TcpConnection tcpConnection) {
System.out.println("当前处于监听状态,不能关闭");
}
/**
* 监听状态可以转换为建立状态
* @param tcpConnection tcp连接信息存储类
*/
@Override
public void established(TcpConnection tcpConnection) {
System.out.println("将进入建立状态");
tcpConnection.setTcpState(new EstablishedTcpState());
}
@Override
public void listening(TcpConnection tcpConnection) {
System.out.println("当前处于监听状态");
}
}
其中该状态下调用建立方法会转变为建立状态。
4.3.2 EstablishedTcpState
定义如下:
/**
* 建立状态类
*/
public class EstablishedTcpState implements TcpState{
/**
* 建立状态可以转换为关闭状态
* @param tcpConnection tcp状态信息存储类
*/
@Override
public void close(TcpConnection tcpConnection) {
System.out.println("将进入关闭状态");
tcpConnection.setTcpState(new CloseTcpState());
}
@Override
public void established(TcpConnection tcpConnection) {
System.out.println("当前处于建立状态");
}
@Override
public void listening(TcpConnection tcpConnection) {
System.out.println("不能转变为监听状态");
}
}
该状态下调用关闭方法,会进入关闭状态。
4.3.3 CloseTcpState
定义如下:
/**
* 关闭连接状态类
*/
public class CloseTcpState implements TcpState{
@Override
public void close(TcpConnection tcpConnection) {
System.out.println("tcp已经连接关闭");
}
@Override
public void established(TcpConnection tcpConnection) {
System.out.println("当前处于关闭状态,不能建立");
}
/**
* 关闭状态下可以转换为监听状态
* @param tcpConnection tcp连接信息存储类
*/
@Override
public void listening(TcpConnection tcpConnection) {
System.out.println("将进入监听状态");
tcpConnection.setTcpState(new ListeningTcpState());
}
}
该状态下调用监听方法会进入监听状态。
4.4 测试
测试demo:
运行结果:
5 总结
这个结构可能看上去与策略模式相似, 但不同点是——在状态模式中, 特定状态知道其他所有状态的存在, 这样才能实现从一个状态到另一个状态的转换; 策略模式的策略之间一般是相互孤立的。
参考文献
[1]. 《设计模式》