您的位置:首页 > 编程语言 > C语言/C++

C++设计模式[十九]状态模式

2015-11-26 20:28 411 查看

状态模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。状态模式的重点在于状态转换,很多时候,对于一个对象的状态,我们都是让这个对象包含一个状态的属性,这个状态属性记录着对象的具体状态,根据状态的不同使用分支结构来执行不同的功能,就像上面的代码那样处理;就像上面说的,类中存在大量的结构类似的分支语句,变得难以维护和理解。



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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: