码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式01-状态模式

时间:2015-08-05 16:15:00      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

  设计模式概念接触到比较早,之前看看感觉各个模式讲的都差不多,可能感悟不深。最近研究一下,通过具体代码示例加深理解。

  今天学习的是状态模式。状态模式主要的精髓在于把各种状态抽象出来,每种状态的业务逻辑在各自的状态中去实现。把整体的业务逻辑抽象成一个具体调用各状态的类。整体的业务逻辑,即是在各状态类之间进行切换,调用。

  下面以自动售货机为例,说明状态模式。自动售货机为一个整体的业务逻辑对象,自动售货机可能有以下几种状态:

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;
}

 技术分享

设计模式01-状态模式

标签:

原文地址:http://www.cnblogs.com/monalood/p/4704973.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!