码迷,mamicode.com
首页 > 其他好文 > 详细

状态模式

时间:2018-12-22 16:39:33      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:temp   tst   oid   measure   splay   使用   多态   切换   als   

一、什么是状态模式
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

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

状态模式

标签:temp   tst   oid   measure   splay   使用   多态   切换   als   

原文地址:https://www.cnblogs.com/yuemw/p/10161024.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!