设计模式概念接触到比较早,之前看看感觉各个模式讲的都差不多,可能感悟不深。最近研究一下,通过具体代码示例加深理解。
今天学习的是状态模式。状态模式主要的精髓在于把各种状态抽象出来,每种状态的业务逻辑在各自的状态中去实现。把整体的业务逻辑抽象成一个具体调用各状态的类。整体的业务逻辑,即是在各状态类之间进行切换,调用。
下面以自动售货机为例,说明状态模式。自动售货机为一个整体的业务逻辑对象,自动售货机可能有以下几种状态:
1.未投币
2.已投币
3.准备出货
4.售罄
自动售货机对象可能有以下几个动作:
1.投币
2.退币
3.按出货按钮
4.出货
类图如下:
代码如下:
自动售货机类:vendingMachin.h
1 /************************************************************************/ 2 /* 3 自动售货机类. 4 */ 5 /************************************************************************/ 6 7 #ifndef __VENDINGMACHIN_H__ 8 #define __VENDINGMACHIN_H__ 9 10 #include "hasMoneyState.h" 11 #include "noMoney.h" 12 #include "soldOut.h" 13 #include "soldState.h" 14 15 class VendingMachin 16 { 17 public: 18 VendingMachin(int count); 19 void putMoney(); 20 void backMoney(); 21 void pressButton(); 22 void outGoods(); 23 24 void setState(MachineState* pstate); 25 int getCount(); 26 MachineState * getNoMoneyState(); 27 MachineState * getHasMoneyState(); 28 MachineState * getSoldState(); 29 MachineState * getSoldOutState(); 30 private: 31 int m_count; 32 MachineState* m_phasMoney; 33 MachineState* m_pnoMoney; 34 MachineState* m_psold; 35 MachineState* m_psoldOut; 36 MachineState* m_pcurrent; 37 }; 38 39 #endif
vendingMachin.cpp
#include "vendingMachin.h" VendingMachin::VendingMachin(int count) { m_phasMoney = new HasMoneyState(this); m_psoldOut = new SoldOut(this); m_psold = new SoldState(this); m_pnoMoney = new NoMoney(this); if (count > 0) { m_count = count; setState(m_pnoMoney); } } int VendingMachin::getCount() { return m_count; } void VendingMachin::setState(MachineState* pstate) { m_pcurrent = pstate; } void VendingMachin::putMoney() { m_pcurrent->putMoney(); } void VendingMachin::backMoney() { m_pcurrent->backMoney(); } void VendingMachin::pressButton() { m_pcurrent->pressButton(); // 如果当前状态为准备出货状态,则按下出货按钮,进行出货 if (m_pcurrent->getState() == eSOLDING) { m_pcurrent->outGoods(); } } void VendingMachin::outGoods() { //m_pcurrent->outGoods(); if (m_count > 0) { m_count--; printf("售出一件商品\n"); } } MachineState* VendingMachin::getHasMoneyState() { return m_phasMoney; } MachineState* VendingMachin::getNoMoneyState() { return m_pnoMoney; } MachineState* VendingMachin::getSoldOutState() { return m_psoldOut; } MachineState* VendingMachin::getSoldState() { return m_psold; }
状态基类:MachineState.h
#ifndef __MACHINESTATE_H__ #define __MACHINESTATE_H__ #include <stdio.h> /************************************************************************/ /* 模拟自动售货机状态基类 对应四种状态 :已投币,未投币,出货,售罄 */ /************************************************************************/ class VendingMachin; enum VendingState{eNOMONEY,eHASMONEY,eSOLDOUT,eSOLDING}; class MachineState { public: virtual ~MachineState(){} // 投钱 virtual void putMoney() = 0; // 退钱 virtual void backMoney() = 0; // 出货 virtual void outGoods() = 0; // 点击出货按钮 virtual void pressButton() = 0; // 获取当前状态 virtual VendingState getState() = 0; }; #endif
以下是四种状态类:
未投币状态类:noMoney.h
/************************************************************************/ /* 未投币状态 */ /************************************************************************/ #ifndef __NOMONEY_H__ #define __NOMONEY_H__ #include "machineState.h" class NoMoney :public MachineState { public: NoMoney(VendingMachin* vm); virtual ~NoMoney(); void putMoney(); void backMoney(); void pressButton(); void outGoods(); VendingState getState(); protected: VendingMachin* m_pVm; }; #endif
noMoney.cpp
#include "noMoney.h" #include "vendingMachin.h" NoMoney::NoMoney(VendingMachin* vm) { m_pVm = vm; } NoMoney::~NoMoney() { } void NoMoney::putMoney() { printf("投币成功!\n"); // 状态设置为已投币 m_pVm->setState(m_pVm->getHasMoneyState()); } void NoMoney::backMoney() { printf("您未投币,想退钱?...\n"); } void NoMoney::pressButton() { printf("您未投币,想拿东西么?...\n"); } void NoMoney::outGoods() { printf("非法状态\n"); } VendingState NoMoney::getState() { return eNOMONEY; }
已投币状态:hasMoneyState.h
#include "machineState.h" #ifndef __HASMONEYSTATE_H__ #define __HASMONEYSTATE_H__ class HasMoneyState :public MachineState { public: HasMoneyState(VendingMachin*vm); virtual ~HasMoneyState(); void putMoney(); void backMoney(); void pressButton(); void outGoods(); VendingState getState(); protected: VendingMachin* m_pVm; }; #endif #include "hasMoneyState.h" #include "vendingMachin.h" HasMoneyState::HasMoneyState(VendingMachin*vm) { m_pVm = vm; } HasMoneyState::~HasMoneyState() { } void HasMoneyState::putMoney() { printf("您已经投过币了,无需再投\n"); } void HasMoneyState::backMoney() { printf("退币成功\n"); // 状态改为未投币 m_pVm->setState(m_pVm->getNoMoneyState()); } void HasMoneyState::pressButton() { printf("您按下了取货按钮\n"); // 状态设置为待出货状态 m_pVm->setState(m_pVm->getSoldState()); } void HasMoneyState::outGoods() { printf("非法状态\n"); } VendingState HasMoneyState::getState() { return eHASMONEY; }
准备出货状态:soldState
/************************************************************************/ /* 出货状态 */ /************************************************************************/ #ifndef __SOLDSTATE_H__ #define __SOLDSTATE_H__ #include "machineState.h" class SoldState :public MachineState { public: SoldState(VendingMachin* vm); virtual ~SoldState(); void putMoney(); void backMoney(); void pressButton(); void outGoods(); VendingState getState(); protected: VendingMachin* m_pVm; }; #endif #include "soldState.h" #include "vendingMachin.h" SoldState::SoldState(VendingMachin* vm) { m_pVm = vm; } SoldState::~SoldState() { } void SoldState::putMoney() { printf("正在出货,请勿投币\n"); } void SoldState::backMoney() { printf("正在出货,没有可退的钱\n"); } void SoldState::pressButton() { printf("正在出货,请勿重复转动手柄\n"); } void SoldState::outGoods() { m_pVm->outGoods(); if (m_pVm->getCount() >0 ) { m_pVm->setState(m_pVm->getNoMoneyState()); } else { printf("商品已经售罄\n"); m_pVm->setState(m_pVm->getSoldOutState()); } } VendingState SoldState::getState() { return eSOLDING; }
售罄状态:soldOut
/************************************************************************/ /* 售罄状态 */ /************************************************************************/ #ifndef __SOLDOUT_H__ #define __SOLDOUT_H__ #include "machineState.h" class SoldOut :public MachineState { public: SoldOut(VendingMachin* vm); virtual ~SoldOut(); void putMoney(); void backMoney(); void pressButton(); void outGoods(); VendingState getState(); protected: VendingMachin* m_pVm; }; #endif #include "soldOut.h" #include "vendingMachin.h" SoldOut::SoldOut(VendingMachin* vm) { m_pVm = vm; } SoldOut::~SoldOut() { } void SoldOut::putMoney() { printf("投币失败,商品已售罄\n"); } void SoldOut::backMoney() { printf("您未投币,想退钱么?...\n"); } void SoldOut::pressButton() { printf("商品售罄,请勿按动按钮\n"); } void SoldOut::outGoods() { printf("非法状态\n"); } VendingState SoldOut::getState() { return eSOLDOUT; }
测试代码:
// State.cpp : 定义控制台应用程序的入口点。 // #include "vendingMachin.h" int main(int argc, char* argv[]) { VendingMachin *vm = new VendingMachin(10); vm->putMoney(); vm->backMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); vm->putMoney(); vm->pressButton(); return 0; }
时间: 2024-11-25 08:21:40