设计模式之状态模式学习

介绍

结构:

  • State——抽象状态角色
    接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。
  • ConcreteState——具体状态角色
    每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。
  • Context——环境角色
    定义客户端需要的接口,并且负责具体状态的切换。
    环境角色具有状态抽象角色定义的所有行为, 具体执行使用委托方式。
  • 状态模式是行为模式之一

优点: 结构清晰; 遵循设计原则; 封装性非常好

缺点:类膨胀

应用: 行为随状态改变而改变的场景; 条件、 分支判断语句的替代者;

UML类图:

简单示例:

#ifndef SIMPLE_STATE_H
#define SIMPLE_STATE_H

#include <iostream>

using namespace std;


class Context;

/**
 * @brief The State class
 * State类,抽象状态类,定义-一个接口以封装与Context的一个特定状态相关的行为。
 */
class State
{
public:
    void virtual Handle(Context *) = 0;
    string virtual stateName() const = 0;
};

/**
 * @brief The Context class
 * Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。
 */
class Context
{
public:
    Context(State *state)
    {
        m_state = state;
    }

    State *getState() const
    {
        return m_state;
    }

    void setState(State * state)
    {
        m_state = state;
        cout<<"更新当前状态:"<<m_state->stateName()<<endl;
    }

    void request()
    {
        m_state->Handle(this);
    }
private:
    State *m_state;
};



/**
 * @brief The ConcreteStateA class
 * ConcreteState类,具体状态,每一个子类实现一个与Context的一一个状态相关的行为。
 */
class ConcreteStateA : public State
{
    void Handle(Context *context) override;
    string stateName() const  override
    {
        return "ConcreteStateA";
    }
};

class ConcreteStateB : public State
{
    void Handle(Context *context) override;
    string stateName() const  override
    {
        return "ConcreteStateB";
    }
};



class ConcreteStateC : public State
{
    void Handle(Context *context) override;
    string stateName() const  override
    {
        return "ConcreteStateC";
    }
};





void ConcreteStateA::Handle(Context *context)
{
    //设置ConcreteStateA 的下一状态是ConcreteStateB
    cout<<"当前状态:"<<stateName()<<endl;
    context->setState( new ConcreteStateB);
}

void ConcreteStateB::Handle(Context *context)
{
    //设置ConcreteStateA 的下一状态是ConcreteStateC
    cout<<"当前状态:"<<stateName()<<endl;
    context->setState( new ConcreteStateC);
}

void ConcreteStateC::Handle(Context *context)
{
    //设置ConcreteStateA 的下一状态是ConcreteStateA
    cout<<"当前状态:"<<stateName()<<endl;
    context->setState( new ConcreteStateA);
}
#endif // SIMPLE_STATE_H

调用:

    Context *c = new Context( new ConcreteStateA);

    c->request();
    c->request();
    c->request();
    c->request();

再来一个大话设计模式上面的示例,工作:

UML类图:

代码:

#ifndef WORK_STATE_H
#define WORK_STATE_H

#include <iostream>

using namespace std;

class Work;

/**
 * @brief The State class
 * 抽象状态
 */
class State
{
public:
    void virtual writeProgram(Work *w) = 0;
};

/**
 * @brief The ForenoonState class
 * 上午工作状态
 */
class ForenoonState: public State
{
public:
    void writeProgram(Work *w) override;
};


class NoonState: public State
{
public:
    void writeProgram(Work *w) override;
};

class AfternoonState: public State
{
public:
    void writeProgram(Work *w) override;
};


class EveningState: public State
{
public:
    void writeProgram(Work *w) override;
};

class SleepingState: public State
{
public:
    void writeProgram(Work *w) override;
};

class RestState: public State
{
public:
    void writeProgram(Work *w) override;
};




class Work
{
public:

    Work()
    {
        //工作初始化未上午工作状态,上午9点开始上班
        m_currentState = new ForenoonState();
    }

    void setState(State *s)
    {
        m_currentState = s;
    }

    double getHour() const
    {
        return  m_hour;
    }

    void setHour(double hour)
    {
        m_hour = hour;
    }

    bool getTaskFinished() const
    {
        return m_isFinished;
    }

    void setTaskFinished(bool finished)
    {
        m_isFinished = finished;
    }

    void writeProgram()
    {
        m_currentState->writeProgram(this);
    }

private:
    double m_hour;//钟点属性,状态转换依据。
    bool m_isFinished;//任务完成属性,是否能下班的依据
    State *m_currentState;
};

//上午
void ForenoonState::writeProgram(Work *w)
{
    if( w->getHour() < 12 )
    {
        cout<<"当前时间: "<<w->getHour()<<"点上午工作,精神百倍"<<endl;
    }
    else
    {
        w->setState( new NoonState);
        w->writeProgram();
    }
}

//中午
void NoonState::writeProgram(Work *w)
{
    if(w->getHour()<13)
    {
        cout<<"当前时间: "<<w->getHour()<<"点  饿了 , 吃午饭, 准备午休"<<endl;
    }
    else
    {
        w->setState(new AfternoonState);
        w->writeProgram();
    }

}

//下午
void AfternoonState::writeProgram(Work *w)
{
    if(w->getHour()<17)
    {
        cout<<"当前时间: "<<w->getHour()<<"点  下午状态不错,继续努力"<<endl;
    }
    else
    {
       w->setState(new EveningState);
       w->writeProgram();
    }
}

//晚上
void EveningState::writeProgram(Work *w)
{
    if(w->getTaskFinished())
    {
        w->setState(new RestState);
        w->writeProgram();
    }
    else
    {
        if(w->getHour()<21)
        {
            cout<<"当前时间: "<<w->getHour()<<"点  加班哦,疲乏之极"<<endl;
        }
        else
        {
           w->setState(new SleepingState);
           w->writeProgram();
        }
    }
}

//休息
void SleepingState::writeProgram(Work *w)
{
    cout<<"当前时间: "<<w->getHour()<<"点  不行,扛不住了,摇睡觉。"<<endl;
}


//下班
void RestState::writeProgram(Work *w)
{
    cout<<"当前时间: "<<w->getHour()<<"点 下班啦,下班啦。"<<endl;
}

#endif // WORK_STATE_H

调用:

 //紧急项目
    Work *emergencyProject = new Work();

    emergencyProject->setHour(9.0);
    emergencyProject->writeProgram();

    emergencyProject->setHour(10.0);
    emergencyProject->writeProgram();

    emergencyProject->setHour(12.0);
    emergencyProject->writeProgram();

    emergencyProject->setHour(13.0);
    emergencyProject->writeProgram();

    emergencyProject->setHour(14.0);
    emergencyProject->writeProgram();

    emergencyProject->setHour(17.0);
    emergencyProject->writeProgram();

    emergencyProject->setTaskFinished(true);
    emergencyProject->setTaskFinished(false);

    emergencyProject->writeProgram();

    emergencyProject->setHour(19.0);
    emergencyProject->writeProgram();

    emergencyProject->setHour(22);
    emergencyProject->writeProgram();

 

 

 

 

展开阅读全文
©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读