• 设计模式C++学习笔记之十九(State状态模式)


    19.1.解释

    概念:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

    main(),客户

    CLiftState,电梯状态抽象类

    CCloseingState,电梯门关闭

    COpenningState,电梯门打开

    CRunningState,电梯运行

    CStoppingState,电梯停止

    CContext,电梯的控制面板

    说明:CContext保持电梯的状态,并提供操作的接口函数。当函数被调用时,CContext直接调用当前状态的相应函数。由状态的接口函数来确定是否可以执行这个动作,以及修改状态为执行这个动作后的状态。

    看代码:第一块是不使用模式的做法,第二块是使用模式的做法,在main()函数里会有调用的方式。

    //ILift.h
    #pragma once
    class ILift
    {
    public:

    ILift(
    void)
    {
    }

    virtual ~ILift(void)
    {
    }
    static const int OPENING_STATE = 1;
    static const int CLOSING_STATE = 2;
    static const int RUNNING_STATE = 3;
    static const int STOPPING_STATE = 4;
    virtual void SetState(int state) = 0;
    virtual void Open() = 0;
    virtual void Close() = 0;
    virtual void Run() = 0;
    virtual void Stop() = 0;
    };

    //Lift.h
    #pragma once
    #include
    "ilift.h"
    class CLift :
    public ILift
    {
    public:
    CLift(
    void);
    ~CLift(void);
    void SetState(int state);
    void Open();
    void Close();
    void Run();
    void Stop();
    private:
    int m_state;
    void OpenWithoutLogic();
    void CloseWithoutLogic();
    void RunWithoutLogic();
    void StopWithoutLogic();
    };

    //Lift.cpp
    #include "StdAfx.h"
    #include
    "Lift.h"
    #include
    <iostream>
    using std::cout;
    using std::endl;

    CLift::CLift(
    void)
    {
    this->m_state = 0;
    }

    CLift::
    ~CLift(void)
    {
    }

    void CLift::SetState(int state)
    {
    this->m_state = state;
    }

    void CLift::Open()
    {
    switch(this->m_state)
    {
    case OPENING_STATE:
    break;
    case CLOSING_STATE:
    this->OpenWithoutLogic();
    this->SetState(OPENING_STATE);
    break;
    case RUNNING_STATE:
    break;
    case STOPPING_STATE:
    this->OpenWithoutLogic();
    this->SetState(OPENING_STATE);
    break;
    }
    }

    void CLift::Close()
    {
    switch(this->m_state)
    {
    case OPENING_STATE:
    this->CloseWithoutLogic();
    this->SetState(CLOSING_STATE);
    break;
    case CLOSING_STATE:
    break;
    case RUNNING_STATE:
    break;
    case STOPPING_STATE:
    break;
    }
    }

    void CLift::Run()
    {
    switch(this->m_state)
    {
    case OPENING_STATE:
    break;
    case CLOSING_STATE:
    this->RunWithoutLogic();
    this->SetState(RUNNING_STATE);
    break;
    case RUNNING_STATE:
    break;
    case STOPPING_STATE:
    this->RunWithoutLogic();
    this->SetState(RUNNING_STATE);
    break;
    }
    }

    void CLift::Stop()
    {
    switch(this->m_state)
    {
    case OPENING_STATE:
    break;
    case CLOSING_STATE:
    this->StopWithoutLogic();
    this->SetState(CLOSING_STATE);
    break;
    case RUNNING_STATE:
    this->StopWithoutLogic();
    this->SetState(CLOSING_STATE);
    break;
    case STOPPING_STATE:
    break;
    }
    }

    void CLift::OpenWithoutLogic()
    {
    cout
    << "电梯门开启..." << endl;
    }

    void CLift::CloseWithoutLogic()
    {
    cout
    << "电梯门关闭..." << endl;
    }

    void CLift::RunWithoutLogic()
    {
    cout
    << "电梯上下跑起来..." << endl;
    }

    void CLift::StopWithoutLogic()
    {
    cout
    << "电梯停止了..." << endl;
    }

    //LiftState.h
    #pragma once
    class CContext;
    class CLiftState
    {
    public:
    CLiftState(
    void);
    virtual ~CLiftState(void);
    void SetContext(CContext *pContext);
    virtual void Open() = 0;
    virtual void Close() = 0;
    virtual void Run() = 0;
    virtual void Stop() = 0;
    protected:
    CContext
    *m_pContext;
    };

    //LiftState.cpp
    #include "StdAfx.h"
    #include
    "LiftState.h"

    CLiftState::CLiftState(
    void)
    {
    }

    CLiftState::
    ~CLiftState(void)
    {
    }

    void CLiftState::SetContext( CContext *pContext )
    {
    m_pContext
    = pContext;
    }

    //CloseingState.h
    #pragma once
    #include
    "liftstate.h"
    class CCloseingState :
    public CLiftState
    {
    public:
    CCloseingState(
    void);
    ~CCloseingState(void);
    void Open();
    void Close();
    void Run();
    void Stop();
    };

    //CloseingState.cpp
    #include "StdAfx.h"
    #include
    "CloseingState.h"
    #include
    "Context.h"
    #include
    <iostream>
    using std::cout;
    using std::endl;

    CCloseingState::CCloseingState(
    void)
    {
    }

    CCloseingState::
    ~CCloseingState(void)
    {
    }

    void CCloseingState::Open()
    {
    this->CLiftState::m_pContext->SetLiftState(CContext::pOpenningState);
    this->CLiftState::m_pContext->GetLiftState()->Open();
    }

    void CCloseingState::Close()
    {
    cout
    << "电梯门关闭..." << endl;
    }

    void CCloseingState::Run()
    {
    this->CLiftState::m_pContext->SetLiftState(CContext::pRunningState);
    this->CLiftState::m_pContext->GetLiftState()->Run();
    }

    void CCloseingState::Stop()
    {
    this->CLiftState::m_pContext->SetLiftState(CContext::pStoppingState);
    this->CLiftState::m_pContext->GetLiftState()->Stop();
    }

    //OpenningState.h
    #pragma once
    #include
    "liftstate.h"
    class COpenningState :
    public CLiftState
    {
    public:
    COpenningState(
    void);
    ~COpenningState(void);
    void Open();
    void Close();
    void Run();
    void Stop();
    };

    //OpenningState.cpp
    #include "StdAfx.h"
    #include
    "OpenningState.h"
    #include
    "Context.h"
    #include
    <iostream>
    using std::cout;
    using std::endl;

    COpenningState::COpenningState(
    void)
    {
    }

    COpenningState::
    ~COpenningState(void)
    {
    }

    void COpenningState::Open()
    {
    cout
    << "电梯门开启..." << endl;
    }

    void COpenningState::Close()
    {
    this->CLiftState::m_pContext->SetLiftState(CContext::pCloseingState);
    this->CLiftState::m_pContext->GetLiftState()->Close();
    }

    void COpenningState::Run()
    {
    //do nothing
    }

    void COpenningState::Stop()
    {
    //do nothing
    }

    //RunningState.h
    #pragma once
    #include
    "liftstate.h"
    class CRunningState :
    public CLiftState
    {
    public:
    CRunningState(
    void);
    ~CRunningState(void);
    void Open();
    void Close();
    void Run();
    void Stop();
    };

    //RunningState.cpp
    #include "StdAfx.h"
    #include
    "RunningState.h"
    #include
    "Context.h"
    #include
    <iostream>
    using std::cout;
    using std::endl;

    CRunningState::CRunningState(
    void)
    {
    }

    CRunningState::
    ~CRunningState(void)
    {
    }

    void CRunningState::Open()
    {
    //do nothing
    }

    void CRunningState::Close()
    {
    //do nothing
    }

    void CRunningState::Run()
    {
    cout
    << "电梯上下跑..." << endl;
    }

    void CRunningState::Stop()
    {
    this->CLiftState::m_pContext->SetLiftState(CContext::pStoppingState);
    this->CLiftState::m_pContext->GetLiftState()->Stop();
    }

    //StoppingState.h
    #pragma once
    #include
    "liftstate.h"
    class CStoppingState :
    public CLiftState
    {
    public:
    CStoppingState(
    void);
    ~CStoppingState(void);
    void Open();
    void Close();
    void Run();
    void Stop();
    };

    //StoppingState.cpp
    #include "StdAfx.h"
    #include
    "StoppingState.h"
    #include
    "Context.h"
    #include
    <iostream>
    using std::cout;
    using std::endl;

    CStoppingState::CStoppingState(
    void)
    {
    }

    CStoppingState::
    ~CStoppingState(void)
    {
    }

    void CStoppingState::Open()
    {
    this->CLiftState::m_pContext->SetLiftState(CContext::pOpenningState);
    this->CLiftState::m_pContext->GetLiftState()->Open();
    }

    void CStoppingState::Close()
    {
    //do nothing
    }

    void CStoppingState::Run()
    {
    this->CLiftState::m_pContext->SetLiftState(CContext::pRunningState);
    this->CLiftState::m_pContext->GetLiftState()->Run();
    }

    void CStoppingState::Stop()
    {
    cout
    << "电梯停止了..." << endl;
    }

    //Contex.h
    #pragma once
    #include
    "LiftState.h"
    #include
    "OpenningState.h"
    #include
    "CloseingState.h"
    #include
    "RunningState.h"
    #include
    "StoppingState.h"
    class CContext
    {
    public:
    CContext(
    void);
    ~CContext(void);
    static COpenningState *pOpenningState;
    static CCloseingState *pCloseingState;
    static CRunningState *pRunningState;
    static CStoppingState *pStoppingState;
    CLiftState
    * GetLiftState();
    void SetLiftState(CLiftState *pLiftState);
    void Open();
    void Close();
    void Run();
    void Stop();
    private:
    CLiftState
    *m_pLiftState;
    };

    //Context.cpp
    #include "StdAfx.h"
    #include
    "Context.h"
    COpenningState
    * CContext::pOpenningState = NULL;
    CCloseingState
    * CContext::pCloseingState = NULL;
    CRunningState
    * CContext::pRunningState = NULL;
    CStoppingState
    * CContext::pStoppingState = NULL;

    CContext::CContext(
    void)
    {
    m_pLiftState
    = NULL;
    pOpenningState
    = new COpenningState();
    pCloseingState
    = new CCloseingState();
    pRunningState
    = new CRunningState();
    pStoppingState
    = new CStoppingState();
    }

    CContext::
    ~CContext(void)
    {
    delete pOpenningState;
    pOpenningState
    = NULL;
    delete pCloseingState;
    pCloseingState
    = NULL;
    delete pRunningState;
    pRunningState
    = NULL;
    delete pStoppingState;
    pStoppingState
    = NULL;
    }

    CLiftState
    * CContext::GetLiftState()
    {
    return m_pLiftState;
    }

    void CContext::SetLiftState(CLiftState *pLiftState)
    {
    this->m_pLiftState = pLiftState;
    this->m_pLiftState->SetContext(this);
    }

    void CContext::Open()
    {
    this->m_pLiftState->Open();
    }

    void CContext::Close()
    {
    this->m_pLiftState->Close();
    }

    void CContext::Run()
    {
    this->m_pLiftState->Run();
    }

    void CContext::Stop()
    {
    this->m_pLiftState->Stop();
    }

    // State.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include
    "ILift.h"
    #include
    "Lift.h"
    #include
    "Context.h"
    #include
    "OpenningState.h"
    #include
    "CloseingState.h"
    #include
    "RunningState.h"
    #include
    "StoppingState.h"
    #include
    <iostream>
    using std::cout;
    using std::endl;

    void DoIt()
    {
    //ILift.h, Lift.h, Lift.cpp
    ILift *pLift = new CLift();
    pLift
    ->SetState(ILift::STOPPING_STATE);//电梯的初始条件是停止状态。
    pLift->Open();//首先是电梯门开启,人进去
    pLift->Close();//然后电梯门关闭
    pLift->Run();//再然后,电梯跑起来,向上或者向下
    pLift->Stop();//最后到达目的地,电梯停下来
    delete pLift;
    }


    void DoNew()
    {
    //LiftState.h, LiftState.cpp, OpenningState.h, CloseingState.h, RunningState.h, StoppingState.h
    //Context.h, Context.cpp
    CContext context;
    CCloseingState closeingState;
    context.SetLiftState(
    &closeingState);
    context.Close();
    context.Open();
    context.Run();
    context.Stop();
    }

    int _tmain(int argc, _TCHAR* argv[])
    {
    cout
    << "----------使用模式之前----------" << endl;
    DoIt();
    cout
    << "----------使用模式之后----------" << endl;
    DoNew();

    _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF
    | _CRTDBG_ALLOC_MEM_DF);
    _CrtDumpMemoryLeaks();
    return 0;
    }

    状态模式也是行为型模式。写了好多天了,才发现如何在页面上插入代码。这样方便多了,看起来也清楚多了。博客园也许需要开个入门贴子,免得新来博客园的童鞋都不大会用。这几天还在学习数据结构中的排序,入排序入手来学习数据结构还是比较容易的。上学的时候只顾着考试了,该学的也都学了,但考完试就全忘掉,已经成为了一种习惯。现在再补回来。鼓励自己加油!一定要做一个学习型的程序员。

  • 相关阅读:
    wpf 3D学习
    vs2010莫名崩溃初探
    Wcf(,service callback client)
    MEF和CompositionContainer学习
    认知Media Queries让浏览器人性化
    移动互联网产品设计的7大误区
    RUP中的迭代模型
    前端工程师的价值体现在哪里?
    做用户研究时,如何挑选合适的用户?
    晒晒 邀请函!感恩节 感谢组织!让我挡上末班车!哈哈!
  • 原文地址:https://www.cnblogs.com/wanggary/p/2024117.html
Copyright © 2020-2023  润新知