C/C++设计模式(十九) 状态模式

概念

State模式也叫状态模式,是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。

 


问题.
每个人、事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下
转移到下一个不同的状态(State)。 最简单的-一个生活中的例子就是:地铁入口处,如果你
放入正确的地铁票,门就会打开让你通过。在出口处也是验票,如果正确你就可以ok,否
则就不让你通过( 如果你动作野蛮,或许会有报警(Alarm),; ))。
有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移)。
通常我们在实现这类系统会使用到很多的Switch/Case语句, Case某种状态,发生什么动作,
Case另外一种状态,则发生另外一种状态。但是这种实现方式至少有以下两个问题:
1)当状态数目不是很多的时候,Switch/Case可能可以搞定。但是当状态数目很多的时
候(实际系统中也正是如此),维护一大组的 Switch/Case语句将是一-件异常困难并且容易出.
错的事情。
2)状态逻辑和动作实现没有分离。在很多的系统实现中,动作的实现代码直接写在状
态的逻辑当中。这带来的后果就是系统的扩展性和维护得不到保证。
 

模式选择
State模式就是被用来解决上面列出的两个问题的,在State模式中我们将状态逻辑和动
作实现进行分离。当一个操作中要维护大量的case分支语句,并且这些分支依赖于对象的
状态。State模式将每-一个分支都封装到独立的类中。State模式典型的结构图为:

角色和职责

Context:用户对象

拥有一个State类型的成员,以标识对象的当前状态;

State:接口或基类

封装与Context的特定状态相关的行为;

ConcreteState:接口实现类或子类

实现了一个与Context某个状态相关的行为。

适用于:

对象的行为,依赖于它所处的当前状态。行为随状态改变而改变的场景。

适用于:通过用户的状态来改变对象的行为。

案例


#include <iostream>
using namespace std;

class Worker;

class State
{
public:
	virtual void doSomeThing(Worker *w) = 0;
};

class Worker
{
public:
	Worker();
	int getHour()
	{
		return m_hour;
	}
	void setHour(int hour)
	{
		m_hour = hour;
	}
	State* getCurrentState()
	{
		return m_currstate;
	}
	void setCurrentState(State* state)
	{
		m_currstate = state;
	}

	void doSomeThing() //
	{
		m_currstate->doSomeThing(this);
	}
private:
	int		m_hour;
	State	*m_currstate; //对象的当前状态
};

class State1 : public State
{
public:
	 void doSomeThing(Worker *w);
};

class State2  : public State
{
public:
	 void doSomeThing(Worker *w);
};

void State1::doSomeThing(Worker *w)
{
	if (w->getHour() == 7 || w->getHour()==8)
	{
		cout << "吃早饭" << endl; 
	}
	else
	{ 
		delete w->getCurrentState();  //状态1 不满足 要转到状态2
		w->setCurrentState(new State2 );
		w->getCurrentState()->doSomeThing(w); //
	}
}


void State2::doSomeThing(Worker *w)
{
	if (w->getHour() == 9 || w->getHour()==10)
	{
		cout << "工作" << endl; 
	}
	else 
	{
		delete w->getCurrentState(); //状态2 不满足 要转到状态3 后者恢复到初始化状态
		w->setCurrentState(new State1); //恢复到当初状态
		cout << "当前时间点:" << w->getHour() << "未知状态" << endl;
	}
}

Worker::Worker()
{
	m_currstate = new State1;
}

void main()
{
	Worker *w1 = new Worker;
	w1->setHour(7);
	w1->doSomeThing();

	w1->setHour(9);
	w1->doSomeThing();

	delete w1;
	cout<<"hello..."<<endl;
	system("pause");
	return ;
}

关注公众号:《码之有道》,一起聊游戏全栈开发!

1、公众号回复:【教程】获取零基础游戏开发客户端+服务端全套教程。
2、公众号回复:【实战】获取企业级实战项目。
3、公众号回复:【资料】获取大学四年整理的所有自学资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值