首页 > 其他分享 >状态模式

状态模式

时间:2022-10-29 16:04:34浏览次数:54  
标签:状态 Context void state 模式 switch context


一、前言

自然界所有事物都有自己的存在状态,比如水有固态、液态、气态,三种不同的心态有着完全不一样的外在特性,我们将事物所处的某一种形态称为状态。


二、状态模式概念

状态模式也称对象的行为模式,是指一个对象在其内部状态发生改变时,它表现的行为和外在属性不一样,这个对象看上去像是改变了它的类型一样。

状态模式的核心是封装,其对应的类图如下所示:

状态模式_c++


从上图中,可以看出状态模式有三类角色:

  • State:抽象状态角色。它是接口或抽象类,负责对象状态的定义,并封装环境角色以实现状态切换;
  • StateX:具体的状态角色。每一个具体的状态必须完成两个职责,即本状态的行为管理及趋向状态的处理【就是本状态下要做的事情,以及本状态如何过渡到其它状态】
  • Context:环境角色。它用来定义客户端需要的接口,并负责具体的状态切换。它是对状态的管理类,其升级形式就是“状态机”;

状态模式的优点

  • 代码接口清晰。避免了过多的switch…case或者if…else语句的使用,使程序更加简洁,提高了系统的可维护性;
  • 封装性非常好。这是状态模式的核心,状态变换放置到类的内部实现,外部调用无需知道状态的变换;
  • 很好地体现了开闭原则和单一职责原则。每一个状态都是一个子类,要增加状态就增加一个子类即可,修改也只修改一个子类;

状态模式的缺点

  • 若状态比较多时,子类就会比较多,会照成类膨胀;在实际项目中,对象的状态最好不要超过5个;

状态模式的应用场景

  • 行为随状态改变而改变的场景。比如权限设计,人员的状态不同,即使执行相同的行为,结果也会不同,这种情况下需要考虑用状态模式;
  • 在程序中有大量分支和条件判断时,可用状态模式让它通过扩展子类实现条件判断处理;

状态模式常用的代码结构:

#include<iostream>

using namespace std;

class Context;//类的前置声明

class State { //抽象状态
public:
virtual void do_something() = 0;
virtual void switch_state() = 0;
};
//==================================================
class StateA :public State { //具体状态
public:
StateA(Context *context) {
this->context = context;
}
void switch_state();
void do_something();

private:
Context *context;
};
//==================================================
class StateB :public State { //具体状态
public:
StateB(Context *context) {
this->context = context;
}
void switch_state();
void do_something();

private:
Context *context;
};
//==================================================
class Context { //上下文的实现
public:
Context() {
stateA = new StateA(this);
stateB = new StateB(this);
this->currentState = stateA;
}
void switch_state() {
currentState->switch_state();
}
void setState(State* state) {
this->currentState = state;
}
State* getStateA() {
return stateA;
}
State* getStateB() {
return stateB;
}

private:
State *stateA, *stateB, *currentState;
};

//==================================================
void StateA::switch_state() {
do_something();
this->context->setState(this->context->getStateB());//转换到B状态的特定写法
};
void StateA::do_something() {
cout << "已转换到状态B" << endl;
};
//==================================================
void StateB::switch_state() {
do_something();
this->context->setState(this->context->getStateA());//转换到B状态的特定写法
};
void StateB::do_something() {
cout << "已转换到状态A" << endl;
};
//==================================================
//主函数
int main() {
Context *context = new Context();
context->switch_state();
context->switch_state();
context->switch_state();
context->switch_state();
return 0;
}

状态模式_状态模式_02


标签:状态,Context,void,state,模式,switch,context
From: https://blog.51cto.com/wangjichuan/5806213

相关文章

  • 设计模式之装饰模式
    概述装饰模式可以在不改变一个对象本身功能的基础上给对象增加额外的新行为。在现实生活中,这种情况也到处存在,例如一张照片,可以不改变照片本身,给它增加一个相框,使得它具有......
  • 【Vue2.0学习】—路由的两种工作模式(六十六)
    【Vue2.0学习】—路由的两种工作模式(六十六)对于一个url来说,什么是hash值?#以及后面的内容就是hash值hash值不会包含在HTTP请求中,即:hash值不会带给服务器hash模式:地址中永远带......
  • 设计模式九(命令模式、解释器模式、迭代器模式、中介者模式)
    命令模式(CommandPattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传......
  • 面试官让你说说react状态管理?
    开发者普遍认为状态是组件的一部分,但是同时却又在剥离状态上不停的造轮子,这不是很矛盾么?对于一个最简单的文本组件而言functionText(){const[text,setText]=......
  • 实现云原生模式​
    云原生基础架构由应用程序来维护,而云原生应用则由基础架构来维护,两者密不可分。这就要求基础架构和应用程序设计必须是简单的。如果一个应用程序比较复杂,则应该采用微服务模......
  • 实现云原生模式
    云原生基础架构由应用程序来维护,而云原生应用则由基础架构来维护,两者密不可分。这就要求基础架构和应用程序设计必须是简单的。如果一个应用程序比较复杂,则应该采用微服务......
  • flink集群安装-Standalone模式
    1、节点规划JobManager:192.168.23.151TaskManager:192.168.23.152TaskManager:192.168.23.153TaskManager:192.168.23.1542、安装配置1)首先在一台机器上安装flink,参......
  • Python RabbitMQ pika的安装及direct路由模式的使用
    RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件,RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有......
  • 浅谈PHP设计模式的观察者模式
    简介观察者模式是行为型模式的一种,定义了对象间一对多的关系。当对象的状态发生变化时候,依赖于它的对象会得到通知。适用场景类似触发钩子事件,可做消息通知、框架底层......
  • js一键切换dark模式 -
    js一键切换dark模式//初始化$(function(){lettheme=$.cookie('theme');if(theme=="dark"){$("body").addClass('dark');$("#theme").add......