• 大话设计模式C++达到-文章16章-国家模式


    一、UML画画



    二、概念

    状态模式(State):当一个对象的内在状态改变时同意改变其行为。这个对象看起来像是改变了其类。


    三、说明

    以下是来自书本和网络的对状态模式的定义和分析:

    (1)状态模式同意对象在内部状态改变时改变它的行为,对象看起来好像改动了它的类。看起来,状态模式好像是神通广大非常厉害似的——竟然可以改动自身的类

    (2)适用场景

    a)状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。

    把状态的推断逻辑转移到表示不同状态的一系列类中,能够把复杂的判 断逻辑简单化。(简单来说,就是把各种if else 转变成了一个个的详细状态,原来if else 每种情况下的操作如今转换到了某个详细状态中)

    b)当一个对象行为取决于它的状态,而且它必须在执行时刻依据状态改变它的行为时。就能够考虑使用状态模式了。


    四、角色

    (1)Context类:在该类内部维护一个ConcreteState子类的一个实例,这个实例定义当前的状态。

    (2)State类:抽象状态类,定义一个 接口以封装与Context的一个特定状态相关的行为。

    (3)ConcreteStateA,ConcreteStateB类:详细状态类。每个子 类实现一个与Context的一个状态相关的行为。


    五、C++实现

    (1)State.h(抽象状态类和详细状态类的声明和定义都在State.h和State.cpp中)

    #ifndef STATE
    #define STATE
    
    //#include "Work.h"
    extern class Work;
    
    class State
    {
    public:
    	State(){};
    	virtual void writeProgram(Work* w){};
    };
    
    class ForenoonState:public State
    {
    public:
    	void writeProgram(Work* w);
    };
    
    class NoonState:public State
    {
    public:
    	void writeProgram(Work* w);
    };
    
    class AfternoonState:public State
    {
    public:
    	void writeProgram(Work* w);
    };
    
    class EveningState:public State
    {
    public:
    	void writeProgram(Work* w);
    };
    
    class SleepingState:public State
    {
    public:
    	void writeProgram(Work* w);
    };
    
    class RestState:public State
    {
    public:
    	void writeProgram(Work* w);
    };
    
    #endif
    


    (2)State.cpp

    #include <iostream>
    #include "State.h"
    #include "Work.h"
    
    using namespace std;
    
    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->getFinish())
    	{
    		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;
    }
    

    (3)Work.h(这里的Work就是状态模式中的Context)

    #ifndef WORK
    #define WORK
    
    #include "State.h"
    
    class Work
    {
    private:
    	State* current;
    
    	double Hour;
    	bool finish;
    
    public:
    	Work();
    	~Work();
    	
    	double getHour();
    	void setHour(double HOUR);
    	
    	bool getFinish();
    	void setFinish(bool FINISH);
    
    	void setState(State* s);
    
    	void writeProgram();
    };
    
    #endif

    (4)Work.cpp

    #include "Work.h"
    
    Work::Work()
    {
    	current=new ForenoonState;
    	Hour=9;
    	finish=false;
    }
    
    Work::~Work()
    {
    	if(current!=0)
    		delete current;
    }
    
    double Work::getHour()
    {
    	return Hour;
    }
    void Work::setHour(double HOUR)
    {
    	Hour=HOUR;
    }
    
    bool Work::getFinish()
    {
    	return finish;
    }
    void Work::setFinish(bool FINISH)
    {
    	finish=FINISH;
    }
    
    void Work::setState(State* s)
    {
    	if(current!=0)
    		delete current;
    
    	current=s;
    }
    
    void Work::writeProgram()
    {
    	current->writeProgram(this);
    }
    

    (5)main.cpp(client)

    #include <iostream>
    #include <cstdlib>
    #include "Work.h"
    //#include "State.h"
    
    using namespace std;
    
    void main()
    {
    	Work emergencyProjects;
    
    	emergencyProjects.setHour(9);
    	emergencyProjects.writeProgram();
    
    	emergencyProjects.setHour(10);
    	emergencyProjects.writeProgram();
    
    	emergencyProjects.setHour(12);
    	emergencyProjects.writeProgram();
    
    	emergencyProjects.setHour(13);
    	emergencyProjects.writeProgram();
    
    	emergencyProjects.setHour(14);
    	emergencyProjects.writeProgram();
    
    	emergencyProjects.setHour(17);
    	emergencyProjects.writeProgram();
    
    	emergencyProjects.setFinish(false);
    
    	emergencyProjects.setHour(19);
    	emergencyProjects.writeProgram();
    
    	emergencyProjects.setHour(22);
    	emergencyProjects.writeProgram();
    
    	system("pause");
    }
    

    注意:上面的代码会出现两个类相互调用的情况。请查看日志:C++中两个类互相引用的解决方法

    (6)执行截图


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    Android
    十大基础有用算法之迪杰斯特拉算法、最小生成树和搜索算法
    【随想】android是个什么东西,andorid机制随想
    【Unity3D】【NGUI】Atlas的动态创建
    Java集合01----ArrayList的遍历方式及应用
    JAVA线程
    VC++的project文件
    selector的button选中处理问题
    单元測试和白盒測试相关总结
    leetCode(40):Path Sum
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4856103.html
Copyright © 2020-2023  润新知