在什么情况下应该采用状态模式?

问题描述 投票:0回答:1

在什么情况下我们应该采用状态模式?

我已经被分配去维护一个项目,项目状态机是通过2000年以上的开关盒实现的。扩展功能将很困难,因此我想对其进行重构。我正在调查状态设计模式,但是有些困惑。

一个简单的例子:

1。初始状态为“ WAIT”,等待用户发送下载命令

2。用户发送下载命令时,进入“连接”状态,连接到服务器

3。建立连接后,进入“下载中”状态,继续接收来自服务器的数据

4。数据下载完成后,移至“ DISCONNECT”,断开与服务器的链接

5。断开连接后,进入“等待”状态,等待用户发送下载命令

A simple state machine pic

  • 方法1:在研究状态模式之前,我认为是一种简单的方法---在不同的函数中包装不同的状态行为,使用函数指针数组指向每个状态函数,并通过调用函数更改状态。

    typedef enum {
        WAIT,
        CONNECT,
        DOWNLOADING,
        DISCONNECT
    }state;
    void (*statefunction[MAX_STATE])(void) = 
    {
        WAITState,
        CONNECTState,
        DOWNLOADINGState,
        DISCONNECTState
    };
    void WAITState(void)
    {
        //do wait behavior
        //while receive download command
        //statefunction[CONNECT]();
    }
    void CONNECTState(void)
    {
        //do connect behavior
        //while connect complete
        //statefunction[DOWNLOADING]();
    }
    void DOWNLOADINGState(void)
    {
        //do downloading behavior
        //while download complete
        //statefunction[DISCONNECT]();
    }
    void DISCONNECTState(void)
    {
        //do disconnect behavior
        //while disconnect complete
        //statefunction[WAIT]();
    }
    
  • 方法2:状态模式将不同的状态及其行为封装在不同的类(面向对象的状态机)中,使用多态性实现不同的状态行为,并为所有具体状态定义一个公共接口。

    class State
    {
    public:
         virtual void Handle(Context *pContext) = 0;
    };
    class Context
    {
    public:
        Context(State *pState) : m_pState(pState){}
    
        void Request()
        {
            if (m_pState)
            {             
                m_pState->Handle(this);           
            }
         }   
    private:
        State *m_pState;
    };
    class WAIT : public State
    {
    public:
        virtual void Handle(Context *pContext)
        {
            //do wait behavior
        }
    };
    class CONNECT : public State
    {
    public:
        virtual void Handle(Context *pContext)
        {
            //do connect behavior
        }
    };
    class DOWNLOADING : public State
    {
    public:
        virtual void Handle(Context *pContext)
        {
            //do downloading behavior
        }
    };
    class DISCONNECT : public State
    {
    public:
        virtual void Handle(Context *pContext)
        {
            //do disconnect behavior
        }
    };
    

我想知道在这种情况下状态模式是否比函数指针更糟糕...仅使用函数指针还可以提高可读性(与切换用例相比),并且更简单。状态模式将创建几个类,并且比仅使用函数指针要复杂得多。使用状态模式有什么优势?

感谢您的时间!

c++ design-patterns state-machine state-pattern
1个回答
0
投票

使用状态模式有什么好处?

首先,需要注意的是,您提供的方法中的both,实际上是the same pattern的示例。其中一种方法描述了基于函数的implementation,而另一种方法则采用了更多的面向对象方法。话虽这么说,该模式本身具有一些优点:

    它限制了状态的数量,程序可以进入,因此-消除了未定义的状态,
  1. 通过添加新状态,而不是重构整个代码,它使应用程序的扩展更容易,
  2. 从公司的角度来看,这是
  3. 安全
  4. ,即使有多个人在同一堂课上工作,由于您已将问题标记为与有关,所以最好考虑该语言提供和要求的语言。尽管classes提供了继承,但是大量的类会大大增加编译时间。因此,在实现方面,如果您的状态机为

    large

,则可能要使用static polymorphism
© www.soinside.com 2019 - 2024. All rights reserved.