23中设计模式C++实现(4)之状态模式(State Pattern)

编程入门 行业动态 更新时间:2024-10-11 01:14:41

23中设计<a href=https://www.elefans.com/category/jswz/34/1771241.html style=模式C++实现(4)之状态模式(State Pattern)"/>

23中设计模式C++实现(4)之状态模式(State Pattern)

简述:

状态模式又叫做有限状态机。适应场景:我们的对象有多种状态,单对象同一时刻只能保持某一种状态,并当内部变量或者内部变量变化时,我们的对象会在这些状态中变换。

UML结构图

  • Context(上下文):定义一个与 Client 交互的接口。它维护对 ConcreteState 对象的引用,可以用该对象来定义当前状态。
  • State(抽象状态):定义接口,来声明每个 ConcreteState 应该做什么。
  • ConcreteState(具体状态):为 State 中定义的方法提供实现。

在上图中,需要特别注意的是红色的虚线箭头。如果没有这个红色的虚线箭头,你会发现,这个结构图与策略模式的结构图一模一样。我查了很多资料也都没有这个红色的虚线箭头,然而这个红色的虚线箭头才是状态模式的关键所在。这个红色虚线箭头表示的意思是,ConcreteState是依赖于Context的,也就是说,具体的状态是依赖于对象的。具体的体现是,ConcreteState的构造函数需要传入Context的指针作为参数的。

优点

  • 避免了大量使用switch/case  、if/else。如果添加新的状态时只需要添加新的状态类,而不需要修改原来的代码,符合开放封闭原则。
  • 每个状态的功能,都放在这个状态类中,各个状态类之间低耦合、高内聚,符合单一职责原则。

缺点

  • 如果状态有很多,将会创建很多类,加大了编程难度。

例子

在ATM上取钱时候,屏幕显示会跟进我们的操作来不断改变状态。我们来模拟其中的四个状态。

// context.h
#ifndef CONTEXT_H
#define CONTEXT_H#include "concrete_state.h"class ATMMachine
{
private:State* Now_State;
public:ATMMachine();~ATMMachine();void SetState(State* New_State);void Request();
};#endif // CONTEXT_H#pragma once
//context.cpp
#include "concrete_state.h"
#include "context.h"ATMMachine::ATMMachine()
{this->Now_State = new InsertYourCard_State(this);
}ATMMachine::~ATMMachine()
{delete Now_State;
}void ATMMachine::SetState(State* New_State)
{Now_State = New_State;
}void ATMMachine::Request()
{Now_State->handle();
}

上面是context.cpp和context.h的代码。我们用这个来定义一个ATMMachine类

// state.h
#ifndef STATE_H
#define STATE_Hclass State
{
public:virtual ~State() { }virtual void handle() = 0;
};#endif 

上面是state.h定义了状态的基类。

// concrete_state.h
#ifndef CONCRETE_STATE_H
#define CONCRETE_STATE_H#include "state.h"
#include "context.h"class ATMMachine;
class PutinNumber_State;class PutinNumber_State : public State
{
public:PutinNumber_State(ATMMachine* p_ATMMachine);~PutinNumber_State() { }void handle();private:ATMMachine* this_ATMMachine;
};class InsertYourCard_State : public State
{
public:InsertYourCard_State(ATMMachine* p_ATMMachine);~InsertYourCard_State() { }void handle();
private:ATMMachine* this_ATMMachine;
};class Home_State : public State
{
public:Home_State(ATMMachine* p_ATMMachine);~Home_State() { }void handle();
private:ATMMachine* this_ATMMachine;
};class WithDraw_State : public State
{
public:WithDraw_State(ATMMachine* p_ATMMachine);~WithDraw_State() { }void handle();
private:ATMMachine* this_ATMMachine;
};#endif // CONCRETE_STATE_H#pragma once
// concrete_state.cpp
#include<iostream>
#include "concrete_state.h"
#include "state.h"//状态:请输入密码
PutinNumber_State::PutinNumber_State(ATMMachine* p_ATMMachine) : this_ATMMachine(p_ATMMachine) { }
void PutinNumber_State::handle()
{int i;std::cout << "请输入您的密码" << std::endl;std::cin >> i;if (i == 100){State* Next_State = new Home_State(this_ATMMachine);this_ATMMachine->SetState(Next_State);delete this;}else{std::cout << "密码错误!!!" << std::endl;}
}//状态:请插入卡
InsertYourCard_State::InsertYourCard_State(ATMMachine* p_ATMMachine) : this_ATMMachine(p_ATMMachine) { }
void InsertYourCard_State::handle()
{int i;std::cout << "请插入您的银行卡" << std::endl;std::cout << "如果银行卡已经插入完毕,请按“1”" << std::endl;std::cin >> i;if (i == 1){State* Next_State = new PutinNumber_State(this_ATMMachine);this_ATMMachine->SetState(Next_State);delete this;}
}//状态:首页
Home_State::Home_State(ATMMachine* p_ATMMachine) : this_ATMMachine(p_ATMMachine) { }
void Home_State::handle()
{int i;std::cout << "进入首页" << std::endl;std::cout << "退卡请按“1" << std::endl;std::cout << "取款请按“2" << std::endl;std::cin >> i;if (i == 1){State* Next_State = new InsertYourCard_State(this_ATMMachine);this_ATMMachine->SetState(Next_State);std::cout << "卡已退出" << std::endl;delete this;}else if (i == 2){State* Next_State = new WithDraw_State(this_ATMMachine);this_ATMMachine->SetState(Next_State);delete this;}
}//状态:取款
WithDraw_State::WithDraw_State(ATMMachine* p_ATMMachine) : this_ATMMachine(p_ATMMachine) { }
void WithDraw_State::handle()
{int i;std::cout << "请输入取款金额" << std::endl;std::cin >> i;std::cout << "已取出金额" << i << "元人民币" << "即将返回首页" << std::endl;State* Next_State = new Home_State(this_ATMMachine);this_ATMMachine->SetState(Next_State);delete this;
}

上面是concrete_state.h和concrete_state.cpp文件,定义了四个状态。

#include <iostream>
#include "context.h"int main()
{ATMMachine my_ATMMachine;while (1){my_ATMMachine.Request();}std::cout << "Hello World!\n";
}

上面是主函数,只需要循环的调用Request()就行啦。

运行结果:

请插入您的银行卡
如果银行卡已经插入完毕,请按“1”
1
请输入您的密码
100
进入首页
退卡请按“1
取款请按“2
2
请输入取款金额
1000
已取出金额1000元人民币即将返回首页
进入首页
退卡请按“1
取款请按“2
1
卡已退出
请插入您的银行卡
如果银行卡已经插入完毕,请按“1”

 

更多推荐

23中设计模式C++实现(4)之状态模式(State Pattern)

本文发布于:2024-03-06 17:46:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1715970.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   状态   State   Pattern

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!