设计模式-状态模式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

在组件构建过程中,某些对象的状态经常面临变化,如何对这些对象的变化进行有效的管理,同时又维持高层模块的稳定,需要使用状态模式


一、问题场景

某些对象的状态如果发生改变,其行为也会随之发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同,如何根据对象的状态来透明的更改对象的行为,而不会为对象操作和状态之间引入耦合。
如下面代码所示

enum NetworkState
{
   
    Network_Open,
    Network_Close,
    Network_Connect
};

class NetworkProcesor
{
   
    NetworkState state;

public:
    void Operation1()
    {
   
        if (state == Network_Open)
        {
   
            // .....
            state = Network_Close;
        }
        else if(state == Network_Close)
        {
   
            // .....
            state = Network_Open;
        }
        else if (state == Network_Connect)
        {
   
            // .....
            state = Network_Open;
        }
        
    }
};

这个和之前的策略模式很像,有大量if-else。违背了”开闭原则“,对扩展开放,对更改关闭

二、状态模式

NetworkState从enum变成基类,每一个派生类自己管理每一种行为,并且定义好切换状态,且每一个派生类都是单例模式。而NetworkProcesor只是内部存了一个基类指针指向不同的状态类,其内部方法都是调用对应的派生类方法,并且更新指向的派生类对象,因此,NetworkProcesor就不会再更变了。

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 = WaitState::GetInstance();
    }


};


class CloseState : public NetworkState
{
   
    static NetworkState *m_instance;

public:
    static NetworkState *GetInstance()
    {
   
        if (m_instance == nullptr)
        {
   
            m_instance = new CloseState();
        }
        return m_instance;
    }

    void Operation1()
    {
   
        // ********
        pNext = CloseState::GetInstance();
    }

    void Operation2()
    {
   
        // ********
        pNext = ConnectState::GetInstance();
    }

    void Operation3()
    {
   
        // ********
        pNext = WaitState::GetInstance();
    }


};


class NetworkProcesor
{
   
    NetworkState* pstate; // 传入状态对象

public:
    NetworkProcesor(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模式将所有与一个特定状态相关的行为都放入一个state子类对象中,再对象切换的过程时,切换相应的对象;但同时维持State的接口,这样实现了具体操作和状态转换之间的解耦;

如果State对象没有实例变量,那么各个上下文可以公用一个state对象来节省开销;

相关推荐

  1. 设计模式状态模式

    2023-12-11 05:54:04       58 阅读
  2. 设计模式——状态模式

    2023-12-11 05:54:04       53 阅读
  3. 设计模式-状态模式

    2023-12-11 05:54:04       49 阅读
  4. 设计模式-状态模式

    2023-12-11 05:54:04       54 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-11 05:54:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-11 05:54:04       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-11 05:54:04       82 阅读
  4. Python语言-面向对象

    2023-12-11 05:54:04       91 阅读

热门阅读

  1. SAP-PP:PP模块相关BAPI持续汇总

    2023-12-11 05:54:04       39 阅读
  2. bisect --- 数组二分查找算法

    2023-12-11 05:54:04       50 阅读
  3. gRPC之gRPC Middleware

    2023-12-11 05:54:04       45 阅读
  4. Python高级算法——动态规划

    2023-12-11 05:54:04       56 阅读
  5. AI 中台

    2023-12-11 05:54:04       49 阅读
  6. [C++] Makefile的语法规则

    2023-12-11 05:54:04       58 阅读
  7. Redis面试题

    2023-12-11 05:54:04       61 阅读
  8. 【Pandas分组聚合】 groupby()、agg() 方法的使用

    2023-12-11 05:54:04       67 阅读
  9. 说说react的事件机制?

    2023-12-11 05:54:04       60 阅读
  10. PostgreSQL 索引介绍和使用事项

    2023-12-11 05:54:04       48 阅读
  11. Android 9.0中sdcard 的权限和挂载问题

    2023-12-11 05:54:04       64 阅读
  12. 2022蓝桥杯数位排序

    2023-12-11 05:54:04       67 阅读