C++设计模式十三--StatePattern(状态模式)
来源:互联网 发布:室内设计在线设计软件 编辑:程序博客网 时间:2024/05/23 02:01
定义
状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
要点
1.状态模式允许一个对象基于内部状态而拥有不同的行为。
2.和程序状态机(PSM)不同,状态模式用类代表状态。
3.Context会将行为委托给当前状态对象。
4.通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。
5.状态模式和策略模式有相同的类图,但它们的意图不同。
6.策略模式通常会用行为或算法来配置Context类,而状态模式允许Context随着状态的改变而改变行为。
7.状态可以有State类或者Context类控制。
8.使用状态模式通常会导致设计中类的数目大量增加。
9.状态类可以被多个Context示例共享。
类图
Context:它拥有一些内部状态。当有人调用request()方法时,它就会被委托到状态来处理(state->handle())。
State:状态接口,所有状态都需要实现这个接口,这样一来,状态之间可以互相替换。
ConcreteStateA/ConcreteStateB:具体状态,可以有很多。处理来自Context的请求。每个ConcreteState都提供了它自己对于请求的实现。所以当Context改变状态时行为也跟着改变。
示例
下面通过实现一个糖果自动售货机,其中状态图如下所示:
State.h
#ifndef STATE_H#define STATE_H#include <iostream>namespace StatePattern {using std::cout;using std::endl;class GumballMachine;class State {public: State(){} virtual ~State(){} virtual void insertQuarter() = 0; virtual void ejectQuarter() = 0; virtual void turnCrank() = 0; virtual void dispense() = 0; };// 未投入硬币class NoQuarterState : public State {private: GumballMachine* m_gumballMachine;public: NoQuarterState(GumballMachine* gumballMachine); virtual ~NoQuarterState(); void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense();};// 投入硬币class HasQuarterState : public State {private: GumballMachine* m_gumballMachine;public: HasQuarterState(GumballMachine* gumballMachine); virtual ~HasQuarterState(); void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense();};// 准备出售糖果class SoldState : public State {private: GumballMachine* m_gumballMachine;public: SoldState(GumballMachine* gumballMachine); virtual ~SoldState(); void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense();};// 糖果售罄class SoldOutState : public State {private: GumballMachine* m_gumballMachine;public: SoldOutState(GumballMachine* gumballMachine); virtual ~SoldOutState(); void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense();};class WinnerState : public State {private: GumballMachine* m_gumballMachine;public: WinnerState(GumballMachine* gumballMachine); virtual ~WinnerState(); void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense();};}#endif
State.cpp
#include "State.h"#include "GumballMachine.h"using namespace StatePattern;NoQuarterState::NoQuarterState(GumballMachine* gumballMachine){ this->m_gumballMachine = gumballMachine;}NoQuarterState::~NoQuarterState(){}void NoQuarterState::insertQuarter(){ cout << "You inserted a quarter" << endl; m_gumballMachine->setState(m_gumballMachine->getHasQuarterState());}void NoQuarterState::ejectQuarter(){ cout << "You haven't inserted a quarter..." << endl;}void NoQuarterState::turnCrank(){ cout << "YOu turned, but there's no quarter" << endl;}void NoQuarterState::dispense(){ cout << "You need to pay first" << endl;} HasQuarterState::HasQuarterState(GumballMachine* gumballMachine){ this->m_gumballMachine = gumballMachine;}HasQuarterState::~HasQuarterState(){}void HasQuarterState::insertQuarter(){ cout << "You can't insert another quarter" << endl;}void HasQuarterState::ejectQuarter(){ cout << "Quarter returned" << endl; m_gumballMachine->setState(m_gumballMachine->getNoQuarterState());}void HasQuarterState::turnCrank(){ cout << "You turned..." << endl; m_gumballMachine->setState(m_gumballMachine->getSoldState());}void HasQuarterState::dispense(){ cout << "No gumball dispensed" << endl;} SoldState::SoldState(GumballMachine* gumballMachine){ this->m_gumballMachine = gumballMachine;}SoldState::~SoldState(){}void SoldState::insertQuarter(){ cout << "Please wait, we're already giving you a gumball" << endl;}void SoldState::ejectQuarter(){ cout << "Sorry, you alread turned the crank" << endl;}void SoldState::turnCrank(){ cout << "Turning twice doesn't get you another gumball" << endl;}void SoldState::dispense(){ m_gumballMachine->releaseBall(); if (m_gumballMachine->getCount() > 0) { m_gumballMachine->setState(m_gumballMachine->getNoQuarterState()); } else { cout << "Oops, out of gumballs" << endl; m_gumballMachine->setState(m_gumballMachine->getSoldOutState()); }} SoldOutState::SoldOutState(GumballMachine* gumballMachine){ this->m_gumballMachine = gumballMachine;}SoldOutState::~SoldOutState(){}void SoldOutState::insertQuarter(){ cout << "You can't insert a quarter, the machine is sold out" << endl;}void SoldOutState::ejectQuarter(){ cout << "You can't eject, you haven't inserted a quarter yet" << endl;}void SoldOutState::turnCrank(){ cout << "You turned, but there are no gumballs" << endl;}void SoldOutState::dispense(){ cout << "No gumball dispensed" << endl;}WinnerState::WinnerState(GumballMachine* gumballMachine){ this->m_gumballMachine = gumballMachine;}WinnerState::~WinnerState(){}void WinnerState::insertQuarter(){}void WinnerState::ejectQuarter(){}void WinnerState::turnCrank(){}void WinnerState::dispense(){}
GumballMachine.h
#ifndef GUMBALLMACHINE_H#define GUMBALLMACHINE_H#include "State.h"namespace StatePattern {class GumballMachine {private: State* m_soldOutState; State* m_noQuarterState; State* m_hasQuarterState; State* m_soldState; State* m_state; int count;public: GumballMachine(int numberGumballs = 0) { m_soldOutState = new SoldOutState(this); m_noQuarterState = new NoQuarterState(this); m_hasQuarterState = new HasQuarterState(this); m_soldState = new SoldState(this); this->count = numberGumballs; m_state = m_soldOutState; if (numberGumballs > 0) { m_state = m_noQuarterState; } } ~GumballMachine(){} void insertQuarter() // 放入硬币 { m_state->insertQuarter(); } void ejectQuarter() // 退钱 { m_state->ejectQuarter(); } void turnCrank() // 转动曲柄,拿到糖果 { m_state->turnCrank(); m_state->dispense(); } void setState(State* state) { this->m_state = state; } void releaseBall() { cout << "A gumball comes rolling out the slot..." << endl; if (0 != count) { count --; } } void refill(int numberGumballs) { this->count = numberGumballs; if (numberGumballs > 0) { m_state = m_noQuarterState; } } State* getSoldOutState() { return m_soldOutState; } State* getNoQuarterState() { return m_noQuarterState; } State* getHasQuarterState() { return m_hasQuarterState; } State* getSoldState() { return m_soldState; } int getCount() { return count; }};}#endif
main.cpp
#include "GumballMachine.h"using namespace StatePattern;int main(){ GumballMachine* gumballMachine = new GumballMachine(1); gumballMachine->insertQuarter(); gumballMachine->turnCrank(); gumballMachine->turnCrank(); delete gumballMachine;}
测试
测试结果如下图所示:
阅读全文
0 0
- C++设计模式十三--StatePattern(状态模式)
- 状态模式 StatePattern
- 对象行为型模式——状态模式(StatePattern)
- Java设计模式之二十三(状态模式)
- Android设计模式(十三)--状态模式
- 大话设计模式读书笔记(十三) 状态模式
- Python设计模式(十三)【状态模式】
- 设计模式之状态模式(c++)
- 设计模式(c++)笔记之十三(Template模式)
- 设计模式(c++)笔记之二十三(Interpreter模式)
- 状态模式(state) -- (模式之十三)
- 设计模式学习系列十三:状态模式(State)
- 二十三种设计模式之状态模式
- 设计模式--(二十三)
- 设计模式(十三)mediator
- 设计模式观后(c++还原之二十三 状态模式)
- C#设计模式(十三)迭代器模式
- 设计模式(十三)适配器模式
- AFNetworking设置https
- react-navigation
- Java中使用Apache POI实现数据的Excel导入和导出
- vim中粘贴数据的时候如何取消自动缩进
- Android 蓝牙4.0 Ble开发(一)
- C++设计模式十三--StatePattern(状态模式)
- Swift:自定义mainstoryboard需要注意的细节
- 大数据量高并发的数据库优化详解
- 隐藏导航栏底部横线 隐藏navigationBar底部的线
- 对比下HTML5和小程序的组件标签的区别
- CentOS-如何配置CentOS的ip
- 595. Big Countries
- Linux文本编辑器
- Python基础-类