状态模式(C++)

定义

允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。

应用场景

  • 在软件构建过程中,某些对象的状态如果改变,其行为也会随之,而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
  • 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?

结构

代码示例

cpp 复制代码
//State.h
/****************************************************/
#ifndef STATE_H
#define STATE_H
#include <iostream>
using namespace std;
class Lamp;
 
// 抽象状态类
class State 
{
public:
	// 析构函数
	virtual ~State() {}
 
	// 操作函数
	virtual void handle(Lamp& context) = 0;
 
};
 
// 具体状态类-开
class StateOn : public State 
{
public:
	// 操作函数
	virtual void handle(Lamp& context);
 
};
 
// 具体状态类-关
class StateOff : public State 
{
public:
	// 操作函数
	virtual void handle(Lamp& context);
 
};
 
// 灯
class Lamp
{
public:
	// 构造函数,默认状态关闭
	Lamp() : m_state(new StateOff()){}
 
	// 析构函数
	~Lamp();
 
	// 设置状态
	void setState(State* state);
 
	// 请求
	void request();
	
private:
	State* m_state;
};

// 操作函数
void StateOn::handle(Lamp& context) {
	cout << "当前状态:打开" << endl;
	cout << "执行操作:关闭" << endl;
	context.setState(new StateOff());
}
 
// 操作函数
void StateOff::handle(Lamp& context) {
	cout << "当前状态:关闭" << endl;
	cout << "执行操作:打开" << endl;
	context.setState(new StateOn());
}
 
// 析构函数
Lamp::~Lamp() {
	if (m_state) {
		delete m_state;
		m_state = nullptr;
	}
}
 
// 设置状态
void Lamp::setState(State* state) {
	if (m_state) {
		delete m_state;
		m_state = nullptr;
	}
	m_state = state;
}
 
// 请求
void Lamp::request() {
	m_state->handle(*this);
}


#endif
cpp 复制代码
//test.cpp
/****************************************************/
#include "State.h"

int main()
{
	Lamp lamp;
	lamp.request(); // 操作灯
	lamp.request(); // 操作灯
	
	return 0;
}

运行结果

要点总结

  • State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
  • 为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的------即要么彻底转换过来,要么不转换。
  • 如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。
相关推荐
whoarethenext36 分钟前
C++ OpenCV 学习路线图
c++·opencv·学习
闻缺陷则喜何志丹1 小时前
【强连通分量 缩点 拓扑排序】P3387 【模板】缩点|普及+
c++·算法·拓扑排序·洛谷·强连通分量·缩点
hutaotaotao1 小时前
c++中的输入输出流(标准IO,文件IO,字符串IO)
c++·io·fstream·sstream·iostream
AL流云。1 小时前
【优选算法】C++滑动窗口
数据结构·c++·算法
qq_429879672 小时前
省略号和可变参数模板
开发语言·c++·算法
CodeWithMe3 小时前
【C/C++】std::vector成员函数清单
开发语言·c++
uyeonashi3 小时前
【QT控件】输入类控件详解
开发语言·c++·qt
zh_xuan8 小时前
c++ 单例模式
开发语言·c++·单例模式
利刃大大10 小时前
【在线五子棋对战】二、websocket && 服务器搭建
服务器·c++·websocket·网络协议·项目
喜欢吃燃面10 小时前
C++刷题:日期模拟(1)
c++·学习·算法