C++设计模式[十九]状态模式
2015-11-26 20:28
411 查看
状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。状态模式的重点在于状态转换,很多时候,对于一个对象的状态,我们都是让这个对象包含一个状态的属性,这个状态属性记录着对象的具体状态,根据状态的不同使用分支结构来执行不同的功能,就像上面的代码那样处理;就像上面说的,类中存在大量的结构类似的分支语句,变得难以维护和理解。
Context:定义客户端感兴趣的接口,并且维护一个ConcreteState子类的实例,这个实例定义当前状态;
State:定义一个接口以封装与Context的一个特定状态相关的行为;
ConcreteState subclasses:每一个子类实现一个与Context的一个状态相关的行为。
它们之间的协作步骤如下:
Context将与状态相关的请求委托给当前的ConcreteState对象处理;
Context可以将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可以访问Context;
Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕,它的客户不再需要直接与状态对象打交道;
看起来像工厂模式,就是简单的将对象的状态和对应状态下的行为分离开来,每一个状态都对应一个类,一个类集中管理一个状态;这个模式也没什么特别的地方,可能就是比if一直判断会好一点,逻辑明确。
一个例子:
状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。状态模式的重点在于状态转换,很多时候,对于一个对象的状态,我们都是让这个对象包含一个状态的属性,这个状态属性记录着对象的具体状态,根据状态的不同使用分支结构来执行不同的功能,就像上面的代码那样处理;就像上面说的,类中存在大量的结构类似的分支语句,变得难以维护和理解。
Context:定义客户端感兴趣的接口,并且维护一个ConcreteState子类的实例,这个实例定义当前状态;
State:定义一个接口以封装与Context的一个特定状态相关的行为;
ConcreteState subclasses:每一个子类实现一个与Context的一个状态相关的行为。
它们之间的协作步骤如下:
Context将与状态相关的请求委托给当前的ConcreteState对象处理;
Context可以将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可以访问Context;
Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕,它的客户不再需要直接与状态对象打交道;
看起来像工厂模式,就是简单的将对象的状态和对应状态下的行为分离开来,每一个状态都对应一个类,一个类集中管理一个状态;这个模式也没什么特别的地方,可能就是比if一直判断会好一点,逻辑明确。
一个例子:
#include"stdafx.h" #include<string> #include <iostream> using namespace std; //观察者 /************************************************************************/ /* 状态模式 */ /************************************************************************/ /* 一个状态接口,不同的状态从该接口中继承出来,想要增加新的状态 时,只需从此接口中派生出新的类即可,适合于当判断较多(多个状态切换频繁)的场合 这里引入一个程序员写工程程序的例子,程序员在一天的不同时间会处于不同的状态 如果程序写不完还得加班,即程序员的状态会随着时间发生改变 */ class Work; /*状态接口State*/ class State { public: virtual void WriteProgram(Work *w) = 0;//写程序的行为(与Work相关的行为) }; //工作类 class Work { private: State *current;//当前状态 double hour; bool taskFinish; public: Work(){taskFinish = false;} void SetTime(double hour){this->hour = hour;} double GetTime(){return this->hour;} //设置状态 void SetState(State *s){current = s;} //设置工程是否完成 void SetFinish(){taskFinish = true;} bool GetFinish(){return taskFinish;} void WriteProgram() {current->WriteProgram(this);} }; //下班休息状态 class RestState : public State { public: void WriteProgram(Work *w) { cout << "当前时间:" << w->GetTime() << "点 工作完成,下班回家了" << endl; } }; //睡眠工作状态 class SleepingState : public State { public: void WriteProgram(Work *w) { cout << "受不了了," << w->GetTime() << "点了,先睡吧" << endl; } }; //晚上工作状态 class EveningState : public State { public: void WriteProgram(Work *w) { //任务完成了,可以休息了 if (w->GetFinish()) { w->SetState(new RestState()); w->WriteProgram(); } else { if (w->GetTime()<21){ cout << "当前时间:" << w->GetTime() << "点 加班了,疲惫至极" << endl; } else { //找过21点 w->SetState(new SleepingState()); w->WriteProgram(); } } } }; //下午工作状态 class AfternoonState : public State { public: void WriteProgram(Work *w) { if (w->GetTime()<17) { cout << "当前时间:" << w->GetTime() << "点 状态还不错,继续努力" << endl; } else { w->SetState(new EveningState()); w->WriteProgram(); } } }; //中午工作状态 class NoonState : public State { public: void WriteProgram(Work *w) { if (w->GetTime()<13) cout << "当前时间:" << w->GetTime() << "点 饿了,午饭:犯困,午休" << endl; else { w->SetState(new AfternoonState()); w->WriteProgram(); } } }; //上午工作状态 class ForenoonState : public State { public: void WriteProgram(Work *w) { if (w->GetTime()<12) cout << "当前时间:" << w->GetTime() << "点 上午工作,精神百倍" << endl; else { w->SetState(new NoonState()); w->WriteProgram(); } } }; void main() { //紧急项目 Work *emergencyProjects = new Work(); emergencyProjects->SetState(new ForenoonState()); emergencyProjects->SetTime(9); emergencyProjects->WriteProgram(); emergencyProjects->SetTime(10); emergencyProjects->WriteProgram(); emergencyProjects->SetTime(12); emergencyProjects->WriteProgram(); emergencyProjects->SetTime(14); emergencyProjects->WriteProgram(); //完成工作,不需要再加班了 //emergencyProjects->SetFinish(); emergencyProjects->SetTime(19); emergencyProjects->WriteProgram(); emergencyProjects->SetTime(22); emergencyProjects->WriteProgram(); system("PAUSE"); }
相关文章推荐
- c++11 async启动异步任务的使用方法
- c++11future简单使用及介绍
- C语言练习作业(五)
- 【C语言】单链表的排序
- 【C语言】查找链表的中间节点及倒数第K个节点
- 【C语言】单链表的逆置
- 有趣的单精度浮点数(float)
- 【C语言】两个有序单链表的合并
- C++学习之模板:模板重载
- const的用法
- 快速排序
- C++矩阵库 Eigen 快速入门
- c++ ip地址的操作 c版
- C++11学习笔记(二)
- C++知识点梳理(1)
- C++ template学习记录(函数模板)
- C++项目调用C#dll项目
- VB与C++之间数据类型的对应关系
- 图像特征LBP原理及C++实现
- Android ndk 入门4 - C++实现