状态模式(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对象,从而节省对象开销。
相关推荐
王老师青少年编程5 分钟前
csp信奥赛C++高频考点专项训练之贪心算法 --【区间贪心】:雷达安装
c++·算法·贪心·csp·信奥赛·区间贪心·雷达安装
elseif1236 分钟前
分组背包1
c++·学习·算法
Rabitebla12 分钟前
【数据结构】动态顺序表实现详解:从原理到接口设计(面试视角)
c语言·开发语言·数据结构·c++·面试·职场和发展
小明同学0115 分钟前
[C++入门]万字长文梳理 C++11 核心特性
c++
郝学胜-神的一滴21 分钟前
Linux 高并发基石:epoll 核心原理 + LT/ET 触发模式深度剖析
linux·运维·服务器·开发语言·c++·网络协议
Hello!!!!!!27 分钟前
C++基础(六)——数组与字符串
c++·算法
天若有情6731 小时前
反向封神!C++ 全局单例不避反用,实现无锁多线程函数独占访问
java·javascript·c++
智者知已应修善业1 小时前
【51单片机调用__TIME__无法实时时间】2023-7-10
c++·经验分享·笔记·算法·51单片机
凤凰院凶涛QAQ1 小时前
《C++转JAVA快速入手系列》:基本通用语法篇
java·开发语言·c++
Shadow(⊙o⊙)2 小时前
C++常见错误解析2.0
开发语言·数据结构·c++·后端·学习·算法