zoukankan      html  css  js  c++  java
  • 状态模式(c++实现)

    状态模式

    模式定义

    状态模式(state),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

    模式动机

    • 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
    • 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式了。

    UML类图

    源码实现

    • state.h
    #include <string>
    class People;
    
    class State
    {
    public:
        State(std::string context);
        virtual ~State();
        virtual void Handle(People* people) = 0;
    
        std::string Content();
    protected:
        std::string m_Content;
    
    private:
        int     m_Time;
    };
    
    • people.h
    #include "state.h"
    
    class People
    {
    public:
        People(State* state);
        void ChangeState(State* state);
        void Show();
        void SetTime(int time);
        int Time();
    private:
        int     m_Now;
        State*    m_State;
    };
    
    • people.cpp
    #include <iostream>
    #include "people.h"
    
    People::People(State* state)
        :m_State(state)
    {
    
    }
    
    void People::ChangeState(State* state)
    {
        m_State = state;
    }
    
    void People::Show()
    {
        std::cout << "来吧,展示!" << std::endl;
        std::cout << "当前状态:" << m_State->Content() << std::endl;
    }
    
    void People::SetTime(int time)
    {
        m_Now = time;
        m_State->Handle(this);
    }
    
    int People::Time()
    {
        return m_Now;
    }
    
    • lifestate.h
    #include "state.h"
    
    class LifeState : public State
    {
    public:
        LifeState(std::string content = "生活状态");
        void Handle(People *people) override;
    };
    
    
    • lifestate.cpp
    #include "lifestate.h"
    #include "workstate.h"
    #include "people.h"
    
    LifeState::LifeState(std::string content)
        :State(content)
    {
    
    }
    
    void LifeState::Handle(People *people)
    {
        int time = people->Time();
        if(time > 9 && time < 18)
            people->ChangeState(new WorkState());
    }
    
    • main.cpp
    #include <iostream>
    #include <memory>
    #include "people.h"
    #include "workstate.h"
    #include "playstate.h"
    #include "lifestate.h"
    
    using namespace std;
    
    int main()
    {
        std::shared_ptr<State> state1 = std::make_shared<WorkState>();
        People p(state1.get());
    
        p.Show();
        p.SetTime(9);
        p.Show();
        p.SetTime(11);
        p.Show();
        p.SetTime(13);
        p.Show();
        p.SetTime(20);
        p.Show();
        p.SetTime(22);
        p.Show();
        return 0;
    }
    
    
    • 运行结果

    来吧,展示!

    当前状态:工作状态

    来吧,展示!

    当前状态:工作状态

    来吧,展示!

    当前状态:工作状态

    来吧,展示!

    当前状态:玩儿乐状态

    来吧,展示!

    当前状态:生活状态

    优点

    模式的优点

    • 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。

      将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易的增加新的状态和转换。

    • 消除庞大的条件分支语句。

    • 状态模式通过把各种状态转移逻辑分布到state的子类之间,来减少相互之间的依赖。

    缺点

    模式的缺点

    • 每个子状态跳转到另外一个子状态是固定的,不能够灵活设置下一个状态,也就是说状态之间装换最好是一对一的,否则就又会出现一个庞大的分支语句。从这点上来看还有点像职责链模式。
  • 相关阅读:
    海居住证我们不得不说的实情![转]
    SQL Server 日期和时间函数
    RESTORE DATABASE命令还原SQLServer 2005 数据库
    asp.net 部署数据库、开始菜单、桌面快捷方式实例(下)
    Server Application Unavailable asp.net 解决办法
    半个月,除了上班时间,而其他时间都不上网,你可以吗?(网络的郁闷)
    唐朝疆域地图[中亚势力范围(公元660年
    偶的偶像 陈松伶写真集
    Sql Server 行转列学习 根据学生表、课程表、学生成绩表统计每个学生的各科成绩和他的总成绩、平均成绩
    DIV+CSS 布局一行两列,左列固定宽度,右列自适应宽度;设置最小宽度,窗口小的时候显示滚动条.
  • 原文地址:https://www.cnblogs.com/wzxNote/p/13321934.html
Copyright © 2011-2022 走看看