Skip to content

Latest commit

 

History

History
45 lines (31 loc) · 2.29 KB

状态.md

File metadata and controls

45 lines (31 loc) · 2.29 KB

状态模式 State

背景

TCP连接时著名的“三次握手,四次挥手”,通信是通过“请求——响应”,但却能执行不同的处理。这里引入“状态”的概念,即提前(根据协议)设计好固定的状态,实现处于某种状态时需要做出的行为。

定义

允许一个对象在其**[1]内部状态改变时改变它的行为**。

难点 & 关键

  1. 状态

    • 有两个要点: 稳定的属性集合(处于不同状态时有不同表现)和状态的转移
  2. 对状态的管理

    • 统一的对外接口
    • 持有状态对象

要素

  • Context —— 有两重身份: [1]客户感兴趣的接口 / [2]管理状态,将与状态有关的请求委托给当前的状态对象
    • 持有状态对象
    • friend class State —— 为了能获取内部状态(状态对象的内部属性)
    • [可选] changeState(State*) —— 外部改变状态
    • 最好有几个状态定义几个静态常量 —— 为了状态转移时不额外增加新的实例(且这种实例创建了 但回收/销毁问题却需要花心思处理)
  • State与ConcreteState —— 具体的子类实例来执行特定于Context中一个状态的操作
  • 状态转换
    • Context 或 ConcreteState子类 都可以进行转换, 但更建议由后者负责转换,因为这样能通过增加子类来增加新的状态和转换,以降低依赖
    • [可选] 用表将输入映射到状态转换上。表的好处是它的规则性, 缺点也很突出。

优点

  • 将与特定状态相关的行为局部化,将不同状态的行为分割开。
  • State使得状态转换显式化,Context中的状态由某个ConcreteState来表现。
  • 当由ConreteState负责转移状态时,易于通过增加子类来增加新的状态和转换。
  • 当State对象没有实例变量(没有内部状态)时,表示它们表示的状态完全以它们的类型来编码,那么Context对象可以共享一个State对象。

不足

  • 具体状态子类的数量会比较多

适用环境

  1. 一个对象的行为取决于它的状态,且需要在运行时根据状态改变它的行为。
  2. 操作中有庞大的多分支条件语句,并且依赖于对象的状态。