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

设计模式——16.状态模式

时间:2018-12-23 19:28:32      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:c++   contex   abstract   技术分享   com   adk   ret   let   execution   

状态模式(State)

在组件构建过程中,当某些对象的状态经常变化时,此时我们需要既对这些对象状态的变化进行管理又维持高层次模块的稳定性,即可以通过“状态变化”类的模式来进行解决。

典型的“状态变化”模式有:

状态模式(State)简介:

让一个对象的行为随着内部的状态类变化而变化,而该对象外部就像是换了类一样。主要解决当控制一个对象状态转换的条件/表达式过于复杂时,把状态的判断逻辑转移至表示不同状态的一系列状态类中。

状态模式的结构:

技术分享图片

C++代码

State抽象类以及具体实现类:


    //file: State.h
    #pragma once
    
    class Context;
    
    ///State
    class State
    {
    public:
        State();
        virtual ~State();
        
        virtual void handle(Context *pC);
    };
    
    ///ConcreteStateA
    class ConcreteStateA : public State
    {
    public:
        static State * Instance();
    
        virtual ~ConcreteStateA();
    
        virtual void handle(Context *pC);
    
    private:
        ConcreteStateA();
        static State * m_State;
    };
    
    
    ///ConcreteStateB
    class ConcreteStateB : public State
    {
    public:
        static State * Instance();
    
        virtual ~ConcreteStateB();
    
        virtual void handle(Context * pC);
    
    private:
        ConcreteStateB();
        static State * m_State;
    };

    //file: State.cpp
    #include "pch.h"
    #include "State.h"
    #include "Context.h"
    #include <iostream>
    using namespace std;
    
    ///State
    State::State() {}
    
    State::~State() {}
    
    void State::handle(Context *pC) {}
    
    
    ///ConcreteStateA
    State *ConcreteStateA::m_State = nullptr;
    
    ConcreteStateA::ConcreteStateA() {}
    
    ConcreteStateA::~ConcreteStateA() {}
    
    State * ConcreteStateA::Instance()
    {
        if (nullptr == m_State)
            m_State = new ConcreteStateA();
        return m_State;
    }
    
    void ConcreteStateA::handle(Context *pC)
    {
        cout << "doing something in State A.\n done,change state to B" << endl;
        pC->changeState(ConcreteStateB::Instance());
    }
    
    
    ///ConcreteStateB
    State * ConcreteStateB::m_State = nullptr;
    
    ConcreteStateB::ConcreteStateB() {}
    
    ConcreteStateB::~ConcreteStateB() {}
    
    State * ConcreteStateB::Instance()
    {
        if (nullptr == m_State)
            m_State = new ConcreteStateB();
        return m_State;
    }
    
    void ConcreteStateB::handle(Context *pC)
    {
        cout << "doing something in State B.\n done,change state to A" << endl;
        pC->changeState(ConcreteStateA::Instance());
    }

Context状态拥有者


    //file: Context.h
    #pragma once
    #include "State.h"
    
    class Context
    {
    public:
        Context(State *pState);
        virtual ~Context();
    
        void changeState(State *pState);
        void request();
    
    private:
        State * m_State;
    };

    //file: Context.cpp
    #include "pch.h"
    #include "Context.h"
    
    Context::Context(State * pState)
    {
        m_State = pState;
    }
    
    Context::~Context() {}
    
    void Context::changeState(State *pState)
    {
        m_State = pState;
    }
    
    void Context::request()
    {
        m_State->handle(this);
    }

客户端代码:


    //file: StatePattern.cpp : This file contains the 'main' function. Program execution begins and ends there.
    #include "pch.h"
    #include <iostream>
    #include "State.h"
    #include "Context.h"
    
    int main()
    {
        Context *context = new Context(ConcreteStateA::Instance());
        context->request();
        context->request();
    
        delete context;
        return 0;
    }

C#代码

State抽象类以及具体实现类:


    //抽象状态类State
    abstract class State
    {
        public abstract void Handle(Context context);
    }
    
    //具体状态类
    class ConcreteStateA : State
    {
        static State m_State;
        public static State Instance
        {
            get
            {
                if (m_State == null)
                    m_State = new ConcreteStateA();
                return m_State;
            }
        }
        public override void Handle(Context context)
        {
            context.ChangeState(ConcreteStateB.Instance);
            Console.WriteLine("The state A Switch to the state B .");
        }
    }

    class ConcreteStateB : State
    {
        static State m_State;
        public static State Instance
        {
            get
            {
                if (m_State == null)
                    m_State = new ConcreteStateB();
                return m_State;
            }
        }
        public override void Handle(Context context)
        {
            context.ChangeState(ConcreteStateC.Instance);
            Console.WriteLine("The state B Switch to the state C .");
        }
    }

    class ConcreteStateC : State
    {
        static State m_State;
        public static State Instance
        {
            get
            {
                if (m_State == null)
                    m_State = new ConcreteStateC();
                return m_State;
            }
        }
        public override void Handle(Context context)
        {
            context.ChangeState(ConcreteStateA.Instance);
            Console.WriteLine("The state C Switch to the state A .");
        }
    }

    //状态拥有者
    class Context
    {
        State m_State = null;

        public Context(State state)
        {
            m_State = state;
        }

        public void Request()
        {
            m_State.Handle(this);
        }

        public void ChangeState(State state)
        {
            m_State = state;
        }
    }

客户端代码:


    class Program
    {
        static void Main(string[] args)
        {
            Context c = new Context(ConcreteStateA.Instance);
            
            c.Request();
            
            c.Request();

            c.Request();

            Console.ReadKey();
        }
    }

运行实例:

技术分享图片

REF

GitHub:

https://github.com/me115/design_patterns

书籍:

设计模式与游戏开发、大话设计模式

设计模式——16.状态模式

标签:c++   contex   abstract   技术分享   com   adk   ret   let   execution   

原文地址:https://www.cnblogs.com/sylvan/p/10165100.html

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