状态模式【行为模式C++】

1.概述

       状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。

  

2.结构

  • State(抽象状态类):定义一个接口用来封装与上下文类的一个特定状态相关的行为,可以有一个或多个行为。
  • ConcreteState(具体状态类):作为抽象状态类的子类,每个子类实现一个与上下文类的一个状态相关的行为。每个具体状态类对应上下文类的一个具体状态,不同的具体状态类其行为有所不同。
  • Context(上下文类):上下文类中维护一个具体状态的实例,通常有多种状态,负责具体状态的切换。

3.实现 

3.1 实例类比

       在日常生活和工作开发中都有状态的问题。你如说马路上的红绿灯,这三个灯光就属于三种状态。再比如说我使用的文档系统,通常有草稿、审阅和批发部三种状态。

       在以往的概念里,我们都会使用if...esle这类语句进行设计,但是这种设计一旦后期的需求发生了改变,那么维护起来相当的复杂!

       一个 文档Document类。 文档可能会处于 草稿Draft 、 ​ 审阅中Moderation和 已发布Published三种状态中的一种。 文档的 publish发布方法在不同状态下的行为略有不同:

  • 处于 草稿状态时, 它会将文档转移到审阅中状态。
  • 处于 审阅状态时, 如果当前用户是管理员, 它会公开发布文档。
  • 处于 已发布状态时, 它不会进行任何操作。  
3.2 具体实现
#include <iostream>
#include <typeinfo>


class Context;

//抽象状态类
class State {
	
protected:
	Context *context_;

public:
	virtual ~State() {
	}

	void set_context(Context *context) {
		this->context_ = context;
	}

	virtual void Status() = 0;
	virtual void Handle() = 0;
};

//上下文类
class Context {
	
private:
	State *state_;

public:
	Context(State *state) : state_(nullptr) {
		this->TransitionTo(state);
	}
	~Context() {
		delete state_;
	}

	void TransitionTo(State *state) {
		std::cout << "Context: Transition to " << typeid(*state).name() << ".\n";
		if (this->state_ != nullptr)
			delete this->state_;
		this->state_ = state;
		this->state_->set_context(this);
	}
	
	void Request1() {
		this->state_->Status();
	}
	void Request2() {
		this->state_->Handle();
	}
};

//已发布状态
class PublishedState : public State {
public:
	void Status() override {
		std::cout << "处于已发布状态.\n";
	}
	void Handle() override {
		std::cout << "结束...\n";
	}
};

//审阅中状态
class ModerationState : public State {
public:
	void Status() override {
		std::cout << "处于审阅中状态.\n";
	};

	void Handle() override {
		this->context_->TransitionTo(new PublishedState);
	}
};


//草稿状态
class DraftState : public State {
public:
	void Status() override {
		std::cout << "处于草稿状态.\n";
	};

	void Handle() override {
		this->context_->TransitionTo(new ModerationState);
	}
};


/**
 * The client code.
 */
void ClientCode() {
	Context *context = new Context(new DraftState);
	context->Request1();
	context->Request2();
	//
	context->Request1();
	context->Request2();
	//
	context->Request1();
	context->Request2();
	delete context;
}

int main() {
	ClientCode();
	return 0;
}
3.3运行结果

4.状态设计模式优缺点

优点:

      通常对有状态的对象进行编程,我们的解决方案是:思考可能存在的所有状态,然后使用 if-else 或 switch-case 语句来进行状态判断,然后再根据不同的状态进行不同的处理。

      大量的if...else的缺点很明显

  1. 违背开闭原则: 当增加一种状态的时候, 需要修改原来的逻辑
  2. 当状态很多的时候, 代码段很长, 臃肿, 不容易维护, 可扩展性差.

     状态模式可以很好地解决这个问题。封装了转换规则,消除了 if-else、switch-case 等条件判断语句,代码更有层次性,且具备良好的扩展力, 可维护性

缺点
  1. 状态模式的使用必然会增加系统类和对象的个数。
  2. 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
  3. 状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

5.应用场景

  1. 一个操作中含有庞大的多分支结构,并且这些分支取决于对象的状态。
  2. 对象的行为依赖于它的状态(例如某些属性值),状态的改变将导致行为的变化。


 

相关推荐

  1. 行为模式-状态模式

    2024-04-23 01:34:03       9 阅读
  2. 行为型设计模式状态模式

    2024-04-23 01:34:03       34 阅读
  3. 状态模式(状态行为分离)

    2024-04-23 01:34:03       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-23 01:34:03       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-23 01:34:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-23 01:34:03       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-23 01:34:03       20 阅读

热门阅读

  1. 2024-04-22(AJAX)

    2024-04-23 01:34:03       13 阅读
  2. Ubuntu22.04.4 - 安装后使用笔记目录-VMware

    2024-04-23 01:34:03       15 阅读
  3. 基于Python对豆瓣电影数据爬虫的设计与实现

    2024-04-23 01:34:03       13 阅读
  4. Es批量删除DeleteByQueryRequestBuilder

    2024-04-23 01:34:03       14 阅读
  5. Unity3D 分块编辑小AStar地图详解

    2024-04-23 01:34:03       11 阅读
  6. 卸载并升级pytorch安装torcheval

    2024-04-23 01:34:03       13 阅读
  7. CV 面试指南—深度学习知识点总结(1)

    2024-04-23 01:34:03       15 阅读
  8. 前端CSS基础2(CSS基本选择器和复合选择器)

    2024-04-23 01:34:03       10 阅读
  9. 面试题

    面试题

    2024-04-23 01:34:03      16 阅读
  10. /bin/sh: 1: arm-linux-g++: not found

    2024-04-23 01:34:03       16 阅读
  11. 【Vue3源码学习】— CH3.2 VNode解析(上)

    2024-04-23 01:34:03       18 阅读