大话设计模式16----状态模式

本文详细介绍了状态模式的概念及应用场景,通过C++代码示例展示了如何在实际项目中运用状态模式解决对象状态变化导致的行为变化问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大话设计模式


1 状态模式(State)结构图




2 对状态模式的一些解释

概念:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

  • 状态模式主要解决的是档控制一个对象状态转换的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一些列类中,可以把复杂的逻辑简化;
  • 将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易的增加新的状态和转换;
  • 状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖;
  • 当一个对象的行为取决于它的状态,并且她必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。


State类:
class State
{
public:
	virtual void Handle(Context *context);
};

ConcreteState:
class ConcreteStateA :public State
{
public:
	void Handle(Context *context)
	{
		context->state = new ConcreteStateB();//设置下一个状态
	}
};

class ConcreteStateB :public State
{
public:
	void Handle(Context *context)
	{
		context->state = new ConcreteStateA();
	}
};

Context类
class Context
{
private:
	State *state;

public:
	Context(State *state)//定义初始状态
	{
		this->state = state;
	}

	void setState(State *state)//设置当前的状态
	{
		this->state = state;
	}

	State *getState()//读取当前的状态
	{
		return this->state();
	}

	void Request()
	{
		state->Handle();//对当前状态下的请求做处理
	}
};

客户端代码:
int main()
{
	Context *context = new Context(new ConcreteStateA());

	context->Request();
}

3 C++代码实现


1 代码结构图:





2 C++源代码:


State.h
#ifndef _STATE_H_
#define _STATE_H_

class Work;

class State
{
public:
	virtual void writeProgram(Work *w);
};

class ForenoonState :public State
{
public:
	void writeProgram(Work *w) override;
};

class NoonState :public State
{
public:
	void writeProgram(Work *w) override;
};

class AfternoonState :public State
{
public:
	void writeProgram(Work *w) override;
};

class EveningState :public State
{
public:
	void writeProgram(Work *w) override;
};

class SleepingState :public State
{
public:
	void writeProgram(Work *w) override;
};

class RestState :public State
{
public:
	void writeProgram(Work *w) override;
};

#endif

State.cpp
#include"State.h"
#include"Work.h"
#include<iostream>

using std::cout;
using std::endl;

void State::writeProgram(Work *w)
{
	cout << "开始写程序" << endl;
}

void ForenoonState::writeProgram(Work *w)
{
	if (w->getHour() < 12)
	{
		cout << "时间:" << w->getHour() << "\t精神百倍!" << endl;
	}
	else
	{
		w->setState(new NoonState());
		w->writeProgram();
	}
}

void NoonState::writeProgram(Work *w)
{
	if (w->getHour() < 13)
	{
		cout << "时间:" << w->getHour() << "\t中午困死了,能不能休息会!" << endl;
	}
	else
	{
		w->setState(new AfternoonState());
		w->writeProgram();
	}
}

void AfternoonState::writeProgram(Work *w)
{
	if (w->getHour() < 17)
	{
		cout << "时间:" << w->getHour() << "\t下午的状态还是不错的,继续加油!" << endl;
	}
	else
	{
		w->setState(new EveningState());
		w->writeProgram();
	}
}

void EveningState::writeProgram(Work *w)
{
	if (w->getFinish())
	{
		cout << "工作完成!  ";
		w->setState(new RestState());
		w->writeProgram();
	}
	else
	{
		if (w->getHour() < 21)
		{
			cout << "时间:" << w->getHour() << "\t加班啊,可恶!" << endl;
		}
		else
		{
			w->setState(new SleepingState());
			w->writeProgram();
		}
	}
}

void SleepingState::writeProgram(Work *w)
{
	cout << "时间:" << w->getHour() << "\t困得不行了,睡着了!" << endl;
}

void RestState::writeProgram(Work *w)
{
	cout << "时间:" << w->getHour() << "\t下班回家!" << endl;
}

Work.h
#ifndef _WORK_H_
#define _WORK_H_

class State;

class Work
{
private:
	State *state;
	double hour;
	bool finish;

public:
	Work();

	void setState(State *state);
	State *getState();

	void setHour(double hour);
	double getHour();

	void setFinish(bool finish);
	bool getFinish();

	void writeProgram();
};

#endif

Work.cpp
#include"Work.h"
#include"State.h"

Work::Work()
{
	state = new ForenoonState();
	this->hour = 9;
	this->finish = false;
}

void Work::setState(State *state)
{
	this->state = state;
}

State * Work::getState()
{
	return this->state;
}

void Work::setHour(double hour)
{
	this->hour = hour;
}

double Work::getHour()
{
	return this->hour;
}

void Work::setFinish(bool finish)
{
	this->finish = finish;
}

bool Work::getFinish()
{
	return this->finish;
}

void Work::writeProgram()
{
	this->state->writeProgram(this);
}

客户端
#include"State.h"
#include"Work.h"
#include<iostream>

using namespace std;

int main()
{
	Work *work = new Work();
	work->setHour(9);
	work->writeProgram();
	work->setHour(12.5);
	work->writeProgram();
	work->setHour(16);
	work->writeProgram();
	work->setHour(20);
	work->writeProgram();
	work->setFinish(true);
	work->writeProgram();
	work->setHour(10);
	//时间重置,那么状态也应该重置一下
	work->setState(new ForenoonState());
	work->setFinish(false);
	work->writeProgram();
	work->setHour(22);
	work->writeProgram();

	system("pause");
	return 0;
}

运行结果:
时间:9 精神百倍!
时间:12.5      中午困死了,能不能休息会!
时间:16        下午的状态还是不错的,继续加油!
时间:20        加班啊,可恶!
工作完成!  时间:20    下班回家!
时间:10        精神百倍!
时间:22        困得不行了,睡着了!
请按任意键继续. . .







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值