博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式(14) - State状态模式
阅读量:4072 次
发布时间:2019-05-25

本文共 7198 字,大约阅读时间需要 23 分钟。

目录


1.意图

State pattern属于行为型模式。

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
简单来说,就是将 “一个大 class + 一堆 if else” 替换为 “一堆小 class”。一堆小 class 就是一堆状态,用一堆状态代替 if else 会更好拓展与维护。
在实际工程代码中,一般是用FSM(有限状态机)来实现。FSM在许多不同的情况下用于建模复杂的实体状态。

2.UML类图

3.GOF角色说明

Context:定义客户感兴趣的接口;维护一个ConcreteState子类的实现。

State:状态接口,即定义一个接口以封装与Context的一个特定状态相关的行为。
ConcreteState subclasses:具体状态子类。每一个子类实现一个与Context的一个状态相关的行为。

4.代码实现

下面例子模拟银行卡的存/取钱流程,客户的帐号状态,随着余额改变而不断变化。

GreenState(余额充足)----状态迁移---->YellowState(收支平衡)----状态迁移---->RedState(透支)---->状态迁移---->GreenState/YellowState,不断循环。
头文件fsm.h实现:

#pragma once#include 
//前向声明class Depositor;//UML中的"State"抽象类class State{public: //当前状态 std::string GetCurrState() const { return _currState; } //储户id Depositor* GetDepositor() const { return _depositor; } void SetDepositor(Depositor* dp) { _depositor = dp; } //余额 double GetBalance() const { return _balance; } void SetBalance(const double balance) { _balance = balance; } virtual void Deposit(const double money) = 0; //存钱 virtual void Withdraw(const double money) = 0; //取钱 virtual void PayInterest() = 0; //利息 protected: std::string _currState; Depositor* _depositor; double _balance; double _interest; double _lowerLimit; double _upperLimit;};//UML中的"ConcreteState"类//绿色状态, 余额充足class GreenState : State{public: GreenState(State* state); void Deposit(const double money); void Withdraw(const double money); void PayInterest(); void TransferNextState(); //扭转到下一个状态private: GreenState(); void Initialize();};//UML中的"ConcreteState"类//黄色状态, 收支基本平衡. 无透支, 但也没有太多余额class YellowState : State{public: YellowState(State* state); YellowState(const double balance, Depositor* dp); void Deposit(const double money); void Withdraw(const double money); void PayInterest(); void TransferNextState(); //扭转到下一个状态private: YellowState(); void Initialize();};//UML中的"ConcreteState"类//红色状态,入不敷出,已透支class RedState : State{public: RedState(State* state); void Deposit(const double money); void Withdraw(const double money); void PayInterest(); void TransferNextState(); //扭转到下一个状态private: RedState(); void Initialize(); double _serviceFee;};//UML中的"Context"类//储户帐号和状态class Depositor{public: Depositor(const std::string id); ~Depositor(); double GetBalance() const; void Deposit(const double money); void Withdraw(const double money); void PayInterest(); void SetState(State* state) { _state = state; } State* GetState() { return _state; }private: State* _state; const std::string _id; Depositor();};

main.cpp 主逻辑实现

#include 
#include "fsm.h"Depositor::Depositor(const std::string id) : _id(id) { //账户默认初始化为余额为0的黄色状态 _state = reinterpret_cast
(new YellowState(0.0, this));}Depositor::~Depositor() { if (_state != nullptr) { delete _state; _state = nullptr; }}double Depositor::GetBalance() const { return _state->GetBalance();}void Depositor::Deposit(const double money) { _state->Deposit(money); std::cout << "Deposited $" << money << std::endl; std::cout << "Balance $" << GetBalance() << std::endl; std::cout << "CurrStatus " << _state->GetCurrState() << std::endl; std::cout << std::endl;}void Depositor::Withdraw(const double money) { _state->Withdraw(money); std::cout << "Withdraw $" << money << std::endl; std::cout << "Balance $" << GetBalance() << std::endl; std::cout << "CurrStatus " << _state->GetCurrState() << std::endl; std::cout << std::endl;}void Depositor::PayInterest() { _state->PayInterest(); std::cout << "------Interest Pay------" << std::endl; std::cout << "Balance $" << GetBalance() << std::endl; std::cout << "CurrStatus " << _state->GetCurrState() << std::endl; std::cout << std::endl;}void GreenState::Initialize() { _currState = "Green"; _interest = 5.0; _lowerLimit = 1000.0; _upperLimit = 100000000.0;}GreenState::GreenState(State* state) { _depositor = state->GetDepositor(); _balance = state->GetBalance(); Initialize();}void GreenState::Deposit(const double money) { _balance += money; TransferNextState();}void GreenState::Withdraw(const double money) { _balance -= money; TransferNextState();}void GreenState::PayInterest() { _balance = _balance * _interest; TransferNextState();}void GreenState::TransferNextState() { if (_balance < 0.0) { _depositor->SetState(reinterpret_cast
(new RedState(this))); delete this; return; } else if (_balance < _lowerLimit) { _depositor->SetState(reinterpret_cast
(new YellowState(this))); delete this; return; } else if (_balance > _upperLimit) { std::cout << "Current depositor is too big" << std::endl; }}void YellowState::Initialize() { _currState = "Yellow"; _interest = 1.0; _lowerLimit = 0.0; _upperLimit = 1000.0;}YellowState::YellowState(State* state) { _balance = state->GetBalance(); _depositor = state->GetDepositor(); Initialize();}YellowState::YellowState(const double balance, Depositor* dp) { _balance = balance; _depositor = dp; Initialize();}void YellowState::Deposit(const double money) { _balance += money; TransferNextState();}void YellowState::Withdraw(const double money) { _balance -= money; TransferNextState();}void YellowState::PayInterest() { _balance = _balance * _interest; TransferNextState();}void YellowState::TransferNextState() { if (_balance < _lowerLimit) { _depositor->SetState(reinterpret_cast
(new RedState(this))); delete this; return; } else if (_balance > _upperLimit) { _depositor->SetState(reinterpret_cast
(new GreenState(this))); delete this; return; }}void RedState::Initialize() { _currState = "Red"; _interest = 0.0; //最多允许透支1000 _lowerLimit = -1000.0; _upperLimit = 0.0; //每次透支的服务费是20 _serviceFee = 20.0;}RedState::RedState(State* state) { _balance = state->GetBalance(); _depositor = state->GetDepositor(); Initialize();}void RedState::Deposit(const double money) { _balance += money; TransferNextState();}void RedState::Withdraw(const double money) { double newFee = money + _serviceFee; if (_balance - newFee < _lowerLimit) { //已到透支上限,无法执行 std::cout << "Can not withdraw due to overdraw too much" << std::endl; } else { _balance -= newFee; }}void RedState::PayInterest() { //not available}void RedState::TransferNextState() { if (_balance > _upperLimit) { _depositor->SetState(reinterpret_cast
(new YellowState(this))); delete this; return; }}int main() { Depositor* dp = new Depositor("Sam"); dp->Withdraw(10.0); dp->Withdraw(1000.0); dp->Deposit(1500.0); dp->Deposit(2000.0); dp->Withdraw(5000.0); dp->Withdraw(3000.0); delete dp; return 0;}

运行结果:

Withdraw  $10
Balance   $-10
CurrStatus Red

Can not withdraw due to overdraw too much

Withdraw  $1000
Balance   $-10
CurrStatus Red

Deposited $1500

Balance   $1490
CurrStatus Yellow

Deposited $2000

Balance   $3490
CurrStatus Green

Withdraw  $5000

Balance   $-1510
CurrStatus Red

Can not withdraw due to overdraw too much

Withdraw  $3000
Balance   $-1510
CurrStatus Red
 

转载地址:http://oleji.baihongyu.com/

你可能感兴趣的文章
大数据入门:Zookeeper结构体系
查看>>
大数据入门:Spark RDD基础概念
查看>>
大数据入门:SparkCore开发调优原则
查看>>
大数据入门:Java和Scala编程对比
查看>>
大数据入门:Scala函数式编程
查看>>
【数据结构周周练】002顺序表与链表
查看>>
C++报错:C4700:使用了非初始化的局部变量
查看>>
【数据结构周周练】003顺序栈与链栈
查看>>
C++类、结构体、函数、变量等命名规则详解
查看>>
C++ goto语句详解
查看>>
【数据结构周周练】008 二叉树的链式创建及测试
查看>>
《软件体系结构》 第九章 软件体系结构评估
查看>>
《软件体系结构》 第十章 软件产品线体系结构
查看>>
《软件过程管理》 第六章 软件过程的项目管理
查看>>
《软件过程管理》 第九章 软件过程的评估和改进
查看>>
《软件过程管理》 第八章 软件过程集成管理
查看>>
分治法 动态规划法 贪心法 回溯法 小结
查看>>
《软件体系结构》 练习题
查看>>
《数据库系统概论》 第一章 绪论
查看>>
《数据库系统概论》 第二章 关系数据库
查看>>