设计模式:状态模式 C++实现

文章目录


前言

今天复习了状态模式,感觉平常可能用的会比较多(解决多分支问题),这里分享给大家。


1. 状态模式的理解

状态模式,就是把所有的状态抽象成一个个具体的类,然后继承一个抽象状态类,在每一个状态类内封装对应状态的行为,符合开放封闭原则,当增加新的状态或减少状态时,只需修改关联的类即可。很适合多分支行为方法的处理,这里的多分支,当然是状态比较多的情况下,如果只有小于4个状态,个人认为还是分支处理简单些。

状态模式正规的定义与类图(引用《大话设计模式》)如下所示:
设计模式:状态模式 C++实现
设计模式:状态模式 C++实现


2. 状态模式的C++实现

这里以一天工作中的工作状态为例实现状态模式。
工作状态的类图结构(引用《大话设计模式》)如下所示:
设计模式:状态模式 C++实现
C++代码实现如下:

#include <iostream>
#include <memory>

//*********************State Pattern*******************
class Work;

//抽象状态类
class State
{
public:
	virtual void WriteProgram(Work* ptrWork) = 0;
};

//工作类
class Work
{
private:
	std::shared_ptr<State> smartState;
	double hour;
	bool finish;

public:
	Work() : hour(0), finish(false), smartState(NULL) {}

	void SetHour(const double h)
	{
		hour = h;
	}

	double GetHour() const
	{
		return hour;
	}

	void SetFinish(bool bFinish)
	{
		finish = bFinish;
	}

	bool GetFinish() const
	{
		return finish;
	}

	void SetState(std::shared_ptr<State> pState)
	{
		smartState = pState;
	}

	std::shared_ptr<State> GetState() const
	{
		return smartState;
	}

	void WriteProgram()
	{
		smartState->WriteProgram(this);
	}

};

//睡眠状态
class SleepingState : public State
{
public:
	void WriteProgram(Work* ptrWork)
	{
		std::cout << "当前时间:" << ptrWork->GetHour() << "点 撑不住了,睡觉吧!" << std::endl;
	}
};

//下班休息状态
class RestState : public State
{
public:
	void WriteProgram(Work* ptrWork)
	{
		std::cout << "当前时间:" << ptrWork->GetHour() << "点 下班回家了!" << std::endl;
	}
};

//傍晚工作状态
class EveningState : public State
{
public:
	void WriteProgram(Work* ptrWork)
	{
		if (ptrWork->GetFinish())
		{
			ptrWork->SetState(std::make_shared<RestState>());
			ptrWork->WriteProgram();
			return;
		}

		if (ptrWork->GetHour() < 21)
		{
			std::cout << "当前时间:" << ptrWork->GetHour() << "点 加班吆,疲惫啊!" << std::endl;
		}
		else
		{//超过21点,转换到睡眠状态
			ptrWork->SetState(std::make_shared<SleepingState>());
			ptrWork->WriteProgram();
		}
	}
};

//下午工作状态
class AfternoonState : public State
{
public:
	void WriteProgram(Work* ptrWork)
	{
		if (ptrWork->GetHour() < 17)
		{
			std::cout << "当前时间:" << ptrWork->GetHour() << "点 下午状态还不错,继续努力!" << std::endl;
		}
		else
		{//超过17点,转换傍晚工作状态
			ptrWork->SetState(std::make_shared<EveningState>());
			ptrWork->WriteProgram();
		}
	}
};

//中午工作状态
class NoonState : public State
{
public:
	void WriteProgram(Work* ptrWork)
	{
		if (ptrWork->GetHour() < 13)
		{
			std::cout << "当前时间:" << ptrWork->GetHour() << "点 饿了,午饭,犯困,午休!" << std::endl;
		}
		else
		{//超过13点,转换下午工作状态
			ptrWork->SetState(std::make_shared<AfternoonState>());
			ptrWork->WriteProgram();
		}
	}
};

//上午工作状态类
class ForenoonState : public State
{
public:
	void WriteProgram(Work* ptrWork)
	{
		if (ptrWork->GetHour() < 12)
		{
			std::cout << "当前时间:" << ptrWork->GetHour() << "点 上午工作,精神百倍!" << std::endl;
		}
		else
		{//超过12点,转换中午工作状态
			ptrWork->SetState(std::make_shared<NoonState>());
			ptrWork->WriteProgram();
		}
	}
};


//************************Test**************************
int main()
{
	std::shared_ptr<Work> work = std::make_shared<Work>();
	work->SetState(std::make_shared<ForenoonState>());

	work->SetHour(9);
	work->WriteProgram();

	work->SetHour(10);
	work->WriteProgram();

	work->SetHour(12);
	work->WriteProgram();

	work->SetHour(13);
	work->WriteProgram();

	work->SetHour(14);
	work->WriteProgram();

	work->SetHour(17);
	work->WriteProgram();

	work->SetFinish(false);
	//work->SetFinish(true);
	//work->WriteProgram();

	work->SetHour(19);
	work->WriteProgram();

	work->SetHour(22);
	work->WriteProgram();

	system("pause");
	return 0;
}

总结

状态模式可以用来解决多分支问题,把复杂的问题简单化,但是对于简单的分支,就没必要使用了。

参考

《大话设计模式》

上一篇:Linux内核同步和异步


下一篇:spring成神之路第三十一篇:aop 概念详解