当前位置: 首页 > article >正文

【GeekBand】C++设计模式笔记18_State_状态模式

1. “状态变化” 模式

  • 在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?“状态变化” 模式为这一问题提供了一种解决方案。
  • 典型模式
    • State
    • Memento

2. State 状态模式

2.1 动机(Motivation)

  • 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
  • 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?

2.2 模式定义

允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。
——《设计模式》GoF

2.3 实例代码

2.3.1 非State模式
enum NetworkState
{
    Network_Open,
    Network_Close,
    Network_Connect,
};


class NetworkProcessor {
    
    NetworkState state;

public:
    
    void Operation1() {
        if (state == Network_Open) {

            //**********
            state = Network_Close;		// 改变状态值
        }
        else if (state == Network_Close) {

            //..........
            state = Network_Connect;
        }
        else if (state == Network_Connect) {

            //$$$$$$$$$$
            state = Network_Open;
        }
    }

    public void Operation2() {
        if (state == Network_Open) {
            
            //**********
            state = Network_Connect;
        }
        else if (state == Network_Close) {

            //.....
            state = Network_Open;
        }
        else if (state == Network_Connect) {

            //$$$$$$$$$$
            state = Network_Close;
        }    
    }

    public void Operation3() {

    }
};

非State模式代码中的类方法中充斥着大量的if分支语句来判断状态的值,从而采取对应的操作,显得很臃肿;而且,当添加一个新状态时,需要在所有的if条件判断语句中添加新的分支。

2.3.2 State模式
// 状态的抽象类
class NetworkState {

public:
    NetworkState* pNext;	// 下一个状态值
    
    virtual void Operation1() = 0;
    virtual void Operation2() = 0;
    virtual void Operation3() = 0;

    virtual ~NetworkState() {}
};

// 继承,实现抽象接口
class OpenState: public NetworkState {
    static NetworkState* m_instance;	// 当前状态属性值
    
public:
	// 单例模式
    static NetworkState* getInstance() {
        if (m_instance == nullptr) {
            m_instance = new OpenState();
        }
        
        return m_instance;
    }

    void Operation1() {
        
        //**********
        pNext = CloseState::getInstance();	// 下一个状态值
    }
    
    void Operation2() {
        
        //..........
        pNext = ConnectState::getInstance();
    }
    
    void Operation3() {
        
        //$$$$$$$$$$
        pNext = OpenState::getInstance();
    }
};

// 代码类似OpenState
class CloseState: public NetworkState { }

// 扩展新状态
//...


class NetworkProcessor { 
    NetworkState* pState;
    
public:
    // 构造函数中传入初始状态值
    NetworkProcessor(NetworkState* pState) {
        this->pState = pState;
    }
    
    void Operation1() {
        //...
        pState->Operation1();
        pState = pState->pNext;	// 将当前状态值切换为下一个状态
        //...
    }
    
    void Operation2() {
        //...
        pState->Operation2();
        pState = pState->pNext;
        //...
    }
    
    void Operation3() {
        //...
        pState->Operation3();
        pState = pState->pNext;
        //...
    }
};

State模式代码中去除了大量的if条件判断分支,将每个状态用一个单独的状态子类来表示,且将与具体状态相关的操作放在子类中。在实际应用中,接口保持不变,利用多态特性,根据状态的真实值从而调用对应的方法。

2.4 结构(Structure)

在这里插入图片描述

2.5 要点总结

  • State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态切换之间的解耦。
  • 为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子的——即要么彻底转换过来,要么不转换。
  • 如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。

http://www.kler.cn/a/458814.html

相关文章:

  • Linux(14)——网络管理
  • AI 智能助手对话系统
  • 人工智能:变革时代的核心驱动力
  • MIT S081 Lab 2 System Calls
  • [2474].第04节:Activiti官方画流程图方式
  • 【玩转23种Java设计模式】行为型模式篇:命令模式
  • 【2024年-6月-21日-开源社区openEuler实践记录】探索 intel-kernel:英特尔架构内核优化之路
  • [TOTP]android kotlin实现 totp身份验证器 类似Google身份验证器
  • 环,域,体,整区,理想,极大理想,
  • 配置hive支持中文注释
  • Lombok是银弹?还是陷阱?
  • golang标准库archive/tar实现打包压缩及解压
  • 《Java核心技术 卷II》流的创建
  • Vue el-data-picker选中开始时间,结束时间自动加半小时
  • 滑动窗口、流量控制和拥塞控制
  • C++笔记-对windows平台上lib和dll的进一步理解(2024-10-21
  • YOLOv8实战车辆目标检测
  • js混淆中 p[‘name‘] 来访问属性的好处
  • 若依前后端分离项目部署(使用docker)
  • C++ 设计模式:职责链模式(Chain of Responsibility)
  • MySQL:一文弄懂时区time_zone
  • 远程调用服务器jupter调试程序
  • word运行时错误‘-2147221164(80040154)’ 没有注册类的解决办法
  • C++ 设计模式:备忘录模式(Memento Pattern)
  • omi friend实战记录
  • Java重要面试名词整理(十六):SpringBoot