状态模式

Posted FatalFlower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状态模式相关的知识,希望对你有一定的参考价值。

概述

《设计模式》一书中对于 “状态模式” 的描述如下:

允许一个对象在其内部状态发生改变时改变它的行为,使得这个对象看起来像修改了它的类

状态模式的 UML 图如下所示:

一般在以下几种情况下使用状态模式:

  • 一个对象的行为取决于它的状态
  • 一个操作中含有庞大的多分支条件语句,且这些分支依赖于该对象的状态

具体示例

一个比较经典的示例就是有关于 TCP 连接的处理,对于一个 TCP 连接来讲,在不同的连接状态下,需要进行的处理是不同的。比如,如果是未建立连接的状态下需要发送数据,那么首先需要建立连接;如果在已经建立连接的前提条件下,那么只需要直接发送数据即可,这种情况的处理就很适合使用状态模式进行处理

首先,定义所有不同状态下进行处理的抽象类 TCPState

public abstract class TCPState 
    public abstract void openConnection();
    public abstract void sendMsg();
    public abstract void close();

之后,对于 TCPConnection 连接对象来讲,需要将对应的处理委托给实际的状态进行处理:

public class TCPConnection 
    private TCPState state;
    
    public void changeState(TCPState state) 
        this.state = state;
    
    
    public void openConnection() 
        this.state.openConnection();
    
    
    public void sendMsg() 
        this.state.sendMsg();
    
    
    public void close() 
        this.state.close();
    

对于不同的连接状态,需要执行不同的处理:

public class EmptyState extends TCPState  // 未建立连接时的有关处理
    @Override
    public void openConnection() 
        createConnection(); // 实际创建连接的过程
    
    
    @Override
    public void sendMsg() 
        throw new IllegalStateException("当前未创建对应的 TCP 连接");
    
    
    @Override
    public void close() 
        throw new IllegalStateException("当前未创建对应的 TCP 连接");
    


public class EstablishState extends TCPState  // 已经建立连接时的有关处理
    @Override
    public void openConnection() 
        throw new IllegalStateException("不能重复打开已有的连接");
    
    
    @Override
    public void sendMsg() 
        sendMessage(); // 发送数据的具体处理
    
    
    @Override
    public void close() 
        closeConnection(); // 具体的关闭连接处理
    

而对于 TCPConnection 对象来讲,现在只需要再维护一个对应的状态机,来处理状态之间的转换即可:

public class Application 
    public static void main(String[] args) 
        TCPConnection conn = new TCPConnection();
        conn.changeState(new EmptyState());
        conn.openConnection();
        // 创建连接结束
        
        conn.changeState(new EstablishState());
        conn.sendMsg("Hello World!");
        conn.close();
    

总结

通过状态模式,可以简化一些冗余的判断处理,加强代码的结构性以及降低对象之间的耦合关系。在涉及到状态之间的转换时,可以通过预先定义对应的状态机来确定每一次操作后的所属状态,从而加强对象的复用


参考:

[1] 《设计模式—可复用面向对象基础》

设计模式 --- 状态模式

状态模式:是游戏中应用最频繁的一种模式

状态经常应用到游戏设计的环节当中;比如 AI人工智能 账号登陆状态 角色状态 场景状态

状态模式说明

技术分享图片

Context:状态拥有者

  是一个具有状态属性的类,可以制定相关的接口,让外界能够得知状态的改变或通过操作让状态改变

  有状态属性的类:比如游戏角色有潜行,攻击,施法等状态  好友上线,脱机,忙碌等状态

  技术分享图片

State:状态接口类

  制定状态的接口,负责规范Context在特定状态下要表现的行为

  技术分享图片

ConcreteState:具体状态类

  继承State 实现Context在特定状态下该有的行为

  技术分享图片技术分享图片

 

  测试结果

  技术分享图片

  输出:

  技术分享图片

以上是关于状态模式的主要内容,如果未能解决你的问题,请参考以下文章

Golang设计模式——状态模式

设计模式 --- 状态模式

设计模式---状态变化模式之state状态模式(State)

23种设计模式(十七)——状态模式状态变化

设计模式状态模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

状态模式(State Pattern)