zoukankan      html  css  js  c++  java
  • 设计模式--状态模式C++实现

    1定义

    当一个状态的内在状态改变时允许其行为改变,这个对象看起来像改变了其类

    2类图

    角色分析

    State抽象状态角色,接口或者抽象类,负责状态定义,并且封装环境角色以实现状态切换

    ConcreteState具体状态角色,完成两个职责:本状态行为管理以及趋向状态处理--==本状态要做的事和本状态如何过度到其他状态

    Context环境角色,定义客户端需要的接口,并且负责具体状态的切换

    实现

    #include<iostream>
    using namespace std;
    
    //前项声明
    class Context;
    //抽象状态类定义
    class State
    {
    protected:
        State(){}
    public:
        virtual~State() = 0
        {};
        void setContext(Context *x)
        {
            _context = x;
        }
        virtual void handler1() = 0;
        virtual void handler2() = 0;
    private:
        Context *_context;
    };
    
    //具体状态定义
    class ConcreteState1 :public State
    {
    public:
        ConcreteState1(){}
        ~ConcreteState1(){}
    
        void handler1()
        {
            cout << "ConcreteState1::handler1" << endl;
        }
        void handler2()
        {
            cout << "ConcreteState1::handler2" << endl;
        }
    private:
    
    };
    
    //具体状态定义
    class ConcreteState2 :public State
    {
    public:
        ConcreteState2(){}
        ~ConcreteState2(){}
    
        void handler1()
        {
            cout << "ConcreteState2::handler1" << endl;
        }
        void handler2()
        {
            cout << "ConcreteState2::handler2" << endl;
        }
    private:
    
    };
    
    //环境类
    class Context
    {
    public:
        Context()
        :Sta1(new ConcreteState1)
        ,Sta2(new ConcreteState2)
        {}
        State* getCurrentState()
        {
            return CurrentState;
        }
        void SetCurrentState(State* s)
        {
            CurrentState = s;
            CurrentState->setContext(this);
        }
        void handler1()
        {
            CurrentState->handler1();
        }
        void handler2()
        {
            CurrentState->handler2();
        }
        ~Context(){}
    private:
        //当前状态则是所有状态中的一种
        State *CurrentState;
        //所有状态应当定义为static比较合适
        State *Sta1;
        State *Sta2;
    };
    void TestState()
    {
        Context * context = new Context();
        context->SetCurrentState(new ConcreteState1());
    
        context->handler1();
        context->handler2();
        context->SetCurrentState(new ConcreteState2());
        context->handler1();
        context->handler2();
    }
    
    
    
     

     3应用

    ①优点

    状态模式隐藏了状态的 变化过程,他的切换引起了行为的变化。我们只看到行为变化,而没有状态变化

    结构清晰,避免过多switch或者if语句的使用

    体现开闭原则和单一职责原则,每个状态都是一个子类

    封装性良好,状态变化在内部体现,外界调用不知道这一点

    ②缺点

    子类越多会带来类膨胀的问题 

    4使用场景

    行为随着状态改变而改变

    条件分之判断语句的替代者

    5注意事项

    状态模式适用于当某个对象在他的状态发生变化时,他的行为也随之变化,也就是行为受状态约束的情况下使用状态模式,而且使用对象时状态不超过5个

    6最佳实践

    TCP三个状态切换:等待状态,连接状态,断开状态。

    工作流开发:状态机管理。

    {

  • 相关阅读:
    LR11
    安装Nginx+uWSGI+Django环境
    MYSQL 安装更新,使用,管理,备份和安全等
    oracle里要查看一条sql的执行情况,有没有走到索引,怎么看?索引不能提高效率?
    大神:python怎么爬取js的页面
    Sublime 编译出来的是 dos格式,不是unix格式
    前天搞了一天?昨天搞了一天?今天搞了半小时
    搞了一宿,弄完了一个POP3协议
    我竟然。。。傻了近一年
    跨进程信息交互真个费事。
  • 原文地址:https://www.cnblogs.com/lang5230/p/5370424.html
Copyright © 2011-2022 走看看