状态模式(state)c++版本

来源:互联网 发布:足球数据app 编辑:程序博客网 时间:2024/06/03 12:43

此为大话设计模式中的状态模式的c++版本
因为此代码中各个类的相互依赖比较严重,所以加入了头文件将声明放置在头文件之中
state.h

/* * state.h * *  Created on: Aug 10, 2017 *      Author: clh01s@163.com */#ifndef _STATE_H_#define _STATE_H_#include <iostream>#include <string>class State;//维护一个concreteState的实例,这个实例定义当前状态class Work{public:    //因为相互包含的问题实现在移至下方    Work();    void Set_state(State *s);    //时间的设置和获取函数    void Set_hour(double hour);    double Get_hour();    void Write_program();    void Set_task_finished(bool finish);    bool Get_task_finished();private:    State *_current;    double _hour = 0;    //任务状态    bool _finish = false;};class State{public:    virtual ~State(){}    //定义一个工作接口交给子类实现    virtual void Write_program(Work *w){};};class ForenoonState:public State{public:    void Write_program(Work *w) override;};class NoonState:public State{public://实现基类的工作函数    void Write_program(Work *w) override;};//下午工作类class AfternoonState:public State{public://实现基类的工作函数    void Write_program(Work *w) override;};//傍晚工作类class EveningState:public State{public://实现基类的工作函数    void Write_program(Work *w) override;};//睡眠类class SleepingState:public State{public://实现基类的工作函数    void Write_program(Work *w) override;};//下班类class RestState:public State{public://实现基类的工作函数    void Write_program(Work *w) override;};#endif /* _STATE_H_ */

state.cpp

/* * state.cpp * *  Created on: Aug 7, 2017 *      Author: clh01s@163.com *      状态模式 *      允许一个对象在其内部状态改变时 *      改变它的行为.对象看起来似乎修 *      改了他的类. */#include "state.h"using namespace std;void ForenoonState::Write_program(Work *w){//检查时间是否小于12点    if(w->Get_hour() < 12)    {        cout<<"上午工作时间,精神饱满!!时间:"<<w->Get_hour()<<endl;    }else    {        //将指针设置为中午工作        w->Set_state(new NoonState());        //继续调用WriteProgram函数检查时间        w->Write_program();    }}void NoonState::Write_program(Work *w){//检查时间是否小于13点    if(w->Get_hour() < 13)    {        cout<<"中午工作时间,饿了,吃饭!!时间:"<<w->Get_hour()<<endl;    }else    {        //将指针设置为下午工作        w->Set_state(new AfternoonState());        //继续调用WriteProgram函数检查时间        w->Write_program();    }}void AfternoonState::Write_program(Work *w){//检查时间是否小于17点    if(w->Get_hour() < 17)    {        cout<<"下午工作时间,精神还行!!时间:"<<w->Get_hour()<<endl;    }else    {        //将指针设置为傍晚工作        w->Set_state(new EveningState());        //继续调用WriteProgram函数检查时间        w->Write_program();    }}void EveningState::Write_program(Work *w){    //检查任务是否完成    if(w->Get_task_finished())    {        //如果是下班就转入下班状态        w->Set_state(new RestState());        w->Write_program();    }else    {    //检查时间是否小于21点        if(w->Get_hour() < 21)        {            cout<<"加班中......时间:"<<w->Get_hour()<<endl;        }else        {            //将指针设置为傍晚工作            w->Set_state(new SleepingState());            //继续调用WriteProgram函数检查时间            w->Write_program();        }    }}void SleepingState::Write_program(Work *w){//因为到深夜所以直接输出吃不消    cout<<"吃不消了,睡着了,时间:"<<w->Get_hour()<<endl;}void RestState::Write_program(Work *w){//完成工作的输出    cout<<"下班回家,时间:"<<w->Get_hour();}//work类的构造函数实现Work::Work(){//将上午工作的类的指针赋值给_current指针变量    _current = new ForenoonState();}//用于修改_current指针变量void Work::Set_state(State *s){    _current = s;}//时间的设置和获取函数void Work::Set_hour(double hour){    _hour = hour;}double Work::Get_hour(){    return _hour;}void Work::Write_program(){//用已经在构造函数被赋上ForenoonState类的地址的_current//调用ForenoonState类的Write_program函数//并且传入Work类的地址让其可以继续调用Work类中的其它函数    _current->Write_program(this);}void Work::Set_task_finished(bool finish){    _finish = finish;}bool Work::Get_task_finished(){    return _finish;}int main(){    //紧急项目    Work *emergencyProjects = new Work();    //上班时间    emergencyProjects->Set_hour(9);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(10);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(11);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(12);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(13);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(14);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(17);    //任务没有完成    emergencyProjects->Set_task_finished(false);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(19);    emergencyProjects->Write_program();    emergencyProjects->Set_hour(22);    emergencyProjects->Write_program();    //释放资源    delete emergencyProjects;    return 0;}

State模式的适用性(摘录自《设计模式》):
1.一个对象的行为取决于他的状态,并且它必须在运行时刻根据状态改变他的行为.
2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖与该对象的状态.这个状态常用一个或多个枚举常量表示.State模式将每个条件分支放入一个独立的类中.这使得你可以根据对象自身的情况将对象的状态作为一个对象,这以对象可以不依赖与其他对象而独立变化.
State模式的优点(摘录自《设计模式》):
1.它将与特定状态相关的行为局部化,并且将不同状态的行为分割开来 State模式将所有与一个特定的状态热爱相关的行为都放入一个对象中.因为所有与状态相关的代码都存在于某个State子类中,所以通过定义新的子类可以很容易的增加新的状态和转换.
2.它使得状态转换显式化 当一个对象仅以内部数据值来定义当前状态时,其状态仅表现为对一些变量的复制,这不够明确.为不同的状态引入独立的对象使得转换变得更加的明确.而且State对象可以保证context不会发生内部状态不一致的情况,因为从context角度看状态转换是原子的——–只需重新绑定一个变量(即context的State对象变量)而无需为多个变量赋值
3.State对象可以被共享 如果State对象没有实例变量——-即它们表示的状态完全以它们的类型来编码——那么各context对象可以共享一个State对象.当状态以这种方式被共享时,它们必然是没有内部状态,只有行为的轻量级对象.

转载请注明源地址:http://blog.csdn.net/clh01s

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子游泳呛水了怎么办 婴儿洗澡呛水了怎么办 小孩脸上长湿疹老是不好怎么办 油耳堵住了耳朵怎么办 耳屎突然变湿该怎么办 小孩有耳屎好硬怎么办 小孩的耳屎深硬怎么办 1岁宝宝喉咙发炎怎么办 牙旁边的肉疼怎么办 鼻头软骨捏的痛怎么办 耳洞发炎肿了怎么办 一上火耳朵就疼怎么办 耳朵像隔了层膜怎么办 感冒引起的耳闷怎么办 5岁儿童视力0.6怎么办 柯基耳朵不立怎么办 宝宝一惊一乍睡觉不踏实怎么办 新婴儿睡觉不踏实怎么办 耳朵里面疼肿了怎么办 生出来的孩子是畸形怎么办 二胎生了缺陷儿怎么办 扣完肚脐眼后疼怎么办 刚出生的婴儿屁股红怎么办 狗狗耳朵流血了怎么办 狗狗不让掏耳朵怎么办 下巴总是反复长脓包怎么办 不胖但有双下巴怎么办 早上起床眼肿了怎么办 小孩鼻梁很塌的怎么办 17岁鼻子是塌的,怎么办 鼻子又塌又翘怎么办 戴眼镜鼻子塌了怎么办 耳朵里长了粉刺怎么办 耳洞太大了怎么办变小 天生嘴唇厚又大怎么办 上嘴唇太厚怎么办还翘 20岁欠债5万怎么办 脑袋撞了个包怎么办 交通事故对方全责但不赔偿怎么办 人格分列症的症状怎么办 子宫肌瘤月经量多怎么办