状态模式

Posted yuemw

tags:

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

一、什么是状态模式
1. 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
  状态模式主要是为了消除庞大的条件分支语句,将各种状态转移逻辑分布到State的子类之间,减少相互间的依赖。
2.应用场合
  当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为,就可以考虑使用状态模式。
3.结构类图

技术分享图片

  我们这里以温度测量判断为例,进行状态模式编码实现。在温度测量仪器的使用中,对于一路通道的温度测量有很多种状态,在此处选取正常、量程溢出、断偶保护三种状态,随着测量点温度的上升,该路测量通道状态在从正常--溢出--断偶切换。

#ifndef STATE_H
#define STATE_H

#include <QDebug>

class TemperatureMeasure;

class State
{
public:
    State() {};
    virtual ~State() {};

    virtual void update(TemperatureMeasure* measure) {};
};

class TemperatureMeasure
{
public:
    TemperatureMeasure(State *state)
        : m_state(state)
        , m_oldState(nullptr)
        , m_temp(0)
    {};
    virtual ~TemperatureMeasure() 
    {
        if (nullptr != m_oldState)
        {
            delete m_oldState;
            m_oldState = nullptr;
        }
        if (nullptr != m_state)
        {
            delete m_state;
            m_state = nullptr;
        }
    };
    
    void setState(State *state)
    {
        if (nullptr != state)
        {
            saveOldState();
            m_state = state;
        }
    };
    State* getState() { return m_state; };

    int getTemperature() { return m_temp; };
    void setTemp(float temp) 
    { 
        m_temp = temp; 
        updateState();
    };

private:
    void updateState() 
    { 
        m_state->update(this); 
        if (nullptr != m_oldState)
        {
            delete m_oldState;
            m_oldState = nullptr;
        }
    };

    void saveOldState() { m_oldState = m_state; };
private:
    State        *m_state;
    State        *m_oldState;
    float        m_temp;
};

class BurnoutState : public State
{
public:
    BurnoutState() {};
    virtual ~BurnoutState() {};

    virtual void update(TemperatureMeasure* measure)
    {
        if (measure->getTemperature() > 120)
        {
            qDebug() << "Current state is Burnout";
        }
    }
};

class OverState : public State
{
public:
    OverState() {};
    virtual ~OverState() {};

    virtual void update(TemperatureMeasure* measure)
    {
        if (measure->getTemperature() < 110 && measure->getTemperature() > 100)
        {
            qDebug() << "Current state is Over!";
        }
        else
        {
            measure->setState(new BurnoutState());
        }
    }
};

class NormalState : public State
{
public:
    NormalState() {};
    virtual ~NormalState() {};

    virtual void update(TemperatureMeasure* measure)
    {
        if (measure->getTemperature() < 100 && measure->getTemperature() > 0)
        {
            qDebug() << "Current state is Normal!";
        }
        else
        {
            measure->setState(new OverState());
        }
    }
};

#if 1
void main()
{
    TemperatureMeasure *measure = new TemperatureMeasure(new NormalState);
    for (int i = 99; i < 123; ++i)
    {
        measure->setTemp(i);
    }
}
#endif // 1

#endif // !State_h

  在实现的过程中,发现状态模式本质上是利用多态替代繁多的条件判断,以上代码是多态一种实现方式,我们在实际的编码过程中,可以根据不同的应用场景,对多态模式进行适当的优化,以便于更好的实现需求。






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

VSCode自定义代码片段13——Vue的状态大管家

VSCode自定义代码片段13——Vue的状态大管家

方向/配置更改后如何维护 ListView 片段状态?

java BottomBarNavigation代码保留片段状态

为不同方向使用不同布局时,在方向更改时保存片段状态

多选模式列表视图行在删除后保持选中状态