状态模式(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 小时前
《LeetCode647 回文子串 || LeetCode 5 最长回文子串》
c++·算法·leetcode·动态规划·哈希算法
Darkwanderor5 小时前
对Linux的进程控制的研究
linux·运维·c++
云泽8086 小时前
从零吃透 C++ 异常:抛出捕获、栈展开、异常重抛与编码规范详解
开发语言·c++·代码规范
REDcker6 小时前
libdatachannel 快速入门
c++·webrtc·datachannel
second608 小时前
第一部分:快速上手 —— 建立 C++ 基本语法与编程范式
开发语言·c++
郝学胜-神的一滴8 小时前
算法实战:最小k个数——大顶堆的优雅解法
开发语言·数据结构·c++·python·程序人生·算法·排序算法
bksczm8 小时前
linux之线程概念和控制
linux·开发语言·c++
hehelm9 小时前
Linux网络编程—TCP字典翻译系统
linux·开发语言·网络·c++·tcp/ip
hansang_IR9 小时前
【记录】「SCOI2016」三道模拟赛/26.7.12
c++·算法
会周易的程序员10 小时前
从零构建多核CPU负载自适应控制系统
linux·c++·笔记·物联网·测试工具