前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >行为型之状态模式C++实现

行为型之状态模式C++实现

作者头像
用户9831583
发布2022-06-16 15:44:50
1910
发布2022-06-16 15:44:50
举报
文章被收录于专栏:码出名企路

现实需求:应用程序中的有些对象可能会根据不同的情况做出不同的行为,这种对象称为有状态的对象,而影响对象行为的一个或多个动态变化的属性称为状态。当有状态的对象与外部事件产生互动时,其内部状态会发生改变,从而使得其行为也随之发生改变。

状态模式:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

核心思想:当控制一个对象状态转换的条件表达式过于复杂时,把相关“判断逻辑”提取出来,放到一系列的状态类当中,这样可以把原来复杂的逻辑判断简单化。

优点:

  1. 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。
  2. 减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
  3. 有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。

缺点:

  1. 状态模式的使用必然会增加系统的类与对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。

主要角色:

  1. 环境角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
  2. 抽象状态角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。
  3. 具体状态角色:实现抽象状态所对应的行为。

案例:

小码路一周的生活方式就是上班,睡觉,吃饭,这种生活呀,小码路日复一日,于是用状态模式记录下自己的一天生活。

第一步:抽象状态

代码语言:javascript
复制
#include <iostream>
using namespace std;

//前置声明
class Xml;
//状态类
class State
{
    public:
        virtual void day(Xml* xml)=0;
};

第二步:具体状态

代码语言:javascript
复制
//上班状态类
class WorkState:public State
{
    public:
        void day(Xml* xml);
};
//睡觉状态
class SleepState:public State
{
    public:
        void day(Xml* xml);
};
//吃饭状态
class EatState:public State
{
    public:
        void day(Xml* xml);
};

第三步:客户角色

代码语言:javascript
复制
//小码路
class Xml
{
    public:
        Xml(){
            state =new WorkState();
        }
        void setState(State* stat)
        {
            state=stat;
        }
        double getHour()
        {
            return hour;
        }
        void setHour(double hou)
        {
            hour=hou;
        }
        void requestday()
        {
            state->day(this);
        }
    private:
        State* state;
        double hour;
};

第四步:状态方法实现

代码语言:javascript
复制
//各个状态的方法实现
void WorkState::day(Xml* xml)
{
    if(xml->getHour() > 9 && xml->getHour()<22)
        cout<<"小码路在上班呀!"<<endl;
    else
    {
        xml->setState(new EatState());
        xml->requestday();
    }
}

void SleepState::day(Xml* xml)
{
    if(xml->getHour() >= 23 || xml->getHour()<6)
        cout<<"小码路在睡觉呀!"<<endl;
    else
    {
        xml->setState(new EatState());
        xml->requestday();
    }
}

void EatState::day(Xml* xml)
{
    if(xml->getHour() > 6 && xml->getHour()<9)
        cout<<"小码路在吃饭呀!"<<endl;
    else if(xml->getHour() >= 23 ||  xml->getHour()<6)
    {
        xml->setState(new SleepState());
        xml->requestday();
    }
    else
    {
        xml->setState(new WorkState());
        xml->requestday();
    }
}

第五步:客户实现

代码语言:javascript
复制
int main()
{
    Xml *xml=new Xml();
    xml->setHour(12);
    cout<<"12点的时候: ";
    xml->requestday();

    xml->setHour(7);
    cout<<"7点的时候: ";
    xml->requestday();

    xml->setHour(24);
    cout<<"24点的时候: ";
    xml->requestday();


    delete xml;
}

显示:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档