设计模式——State(状态)模式

目录

  • 前言
  • 1 定义
  • 2 适用性
  • 3 结构
    • 3.1 结构图
    • 3.2 参与者
  • 4 应用举例
    • 4.1 State——TcpState
    • 4.2 Context——TcpConnection
    • 4.3 ConcreteState——ListeningTcpState、EstablishedTcpState和CloseTcpState
      • 4.3.1 ListeningTcpState
      • 4.3.2 EstablishedTcpState
      • 4.3.3 CloseTcpState
    • 4.4 测试
  • 5 总结
  • 参考文献

前言

考虑一个对象对于不同阶段,不同状态有不同的表现,如tcp连接的监听、建立和关闭。如果使用if else判断来处理将增大复杂度,甚至后续有新状态不利于代码解耦合。而State模式有利于解决这种情况。

1 定义

State(状态)模式:允许一个对象在其状态改变时改变自身行为。

2 适用性

  • 一个对象的行为取决于它的状态,并且是根据它运行时状态改变它的行为。
  • 一个操作有复杂的多分支条件语句,而且判断条件跟对象状态有关。

3 结构

3.1 结构图

State模式结构图如下:
设计模式——State(状态)模式_第1张图片

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

这几个状态转换情况简化为下面图
设计模式——State(状态)模式_第2张图片

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:
设计模式——State(状态)模式_第3张图片
运行结果
设计模式——State(状态)模式_第4张图片

5 总结

这个结构可能看上去与策略模式相似, 但不同点是——在状态模式中, 特定状态知道其他所有状态的存在, 这样才能实现从一个状态到另一个状态的转换; 策略模式的策略之间一般是相互孤立的。

参考文献

[1]. 《设计模式》

你可能感兴趣的:(设计模式,java,后端,设计模式,状态模式)