zoukankan      html  css  js  c++  java
  • 【设计模式】状态模式 改进后的

    1、简单谈谈

     
    状态模式

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


    状态模式要解决的问题是:当控制一个对象状态转换的条件表达式过于复杂时的情况,
    把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

    优点:简化了一个对象的状态转换和行为改变的代码,把这部分代码放在了【状态类】
    中,需要注意的一点是:在【状态类】中,每个不同的【状态值】也许会被“串起来”
    成为一条链,这样就能保证设置不同的“离散的”【状态值】时,可以在“链上”有
    有个对应的处理(行为)。

    缺点:在【状态类】在要引用【客户类】,而在【客户类】中也要用到【状态类】,
    两个类要互相引用。 耦合度稍高。

    2、代码为例

    //状态抽象基类
    class CState
    {
    public: 
        CState();
        virtual ~CState(); 
        virtual void Show(CMe* pMe) = 0;   
    };
    
    CState::CState(){}
    CState::~CState(){}
    
    
    //单身状态类
    class CSingle : public CState
    {
    public:
        CSingle();
        virtual ~CSingle();
        virtual void Show(CMe* pMe);
    };
    
    CSingle::CSingle(){}
    CSingle::~CSingle(){}
    void CSingle::Show(CMe* pMe)
    {
        if(NULL == pMe) return;
        int nAge = pMe->GetAge();
    
        //if .. else 把状态串成了一条链,得以让每个状态都有一个对应的处理。
        if(nAge < 18)
        {
            cout << endl << "哥哥今年才 " << nAge << " 岁啊,还不能找女朋友啊啊 单身啊!! " <<endl;
        }
        else
        {
            pMe->SetState(new CWithGirl());
            pMe->ShowMsg();
        }
    
    }
    
    
    //有女朋友状态类
    class CWithGirl : public CState
    {
    public:
        CWithGirl();
        virtual ~CWithGirl();
        virtual void Show(CMe* pMe) ;
    };
    
    CWithGirl::CWithGirl(){}
    CWithGirl::~CWithGirl(){}
    void CWithGirl::Show(CMe* pMe)
    {
        if(NULL == pMe) return;
        int nAge = pMe->GetAge();
        if(nAge >= 18)
        {
            cout << endl << "哥哥今年已经 " << nAge << " 岁了啊 哈哈 ,可以有女朋友了啊啊 哈哈哈!!" << endl;
        } 
    }
    
    
    
    //我 类
    class CMe
    {
    public:
        CMe();
        virtual ~CMe();
        void SetState(CState* pState);  //设置状态
        void ShowMsg();                    //显示此状态的信息, 供
        int GetAge() const;                //获取年龄
        void SetAge(int nAge);            //设置年龄
    
    protected:
        CState* m_ptrState;             //状态
        int m_nAge;                        //年龄
    };
    
    CMe::CMe() : m_ptrState(NULL), m_nAge(0){}
    CMe::~CMe(){}
    void CMe::SetState(CState* pState)  //状态的改变放在State类中
    {
        m_ptrState = pState;
    }
    void CMe::ShowMsg()                 //不同状态对应的不同行为 表现在 State类中的Show函数
    {
        m_ptrState->Show(this);
    }
    int CMe::GetAge() const {return m_nAge;}
    void CMe::SetAge(int nAge) {this->m_nAge = nAge;}

    客户端

    int _tmain(int argc, _TCHAR* argv[])
    { 
        //对客户来说,只需要设置CMe类的不同年龄,而每个年龄(状态)对应
        //的行为并不在CMe类中实现,而是在State类中实现
        CMe me1;
        me1.SetAge(16); 
        me1.ShowMsg();
    
        cout << endl << endl;
    
        me1.SetAge(20);  //16变为20,相当于状态的改变
        me1.ShowMsg();   //同样的一个ShowMsg方法,在不同状态的时候其行为也不一样
    
        cout << endl << endl;
    
        return 0;
    }

    3、补充说明

    有一个待解决的问题,就是两个类的相互引用,关键是先出现的类中引用了后出现类中的函数,这是问题,所以,这篇,没有执行结果截图

  • 相关阅读:
    java正则表达式(九)
    java正则表达式(八)
    java正则表达式(十)
    正确理解ThreadLocal
    Class.getResource与ClassLoader.getResource()区别
    seajs中define方法的id和dependencies参数
    seajs研究一二三
    十八年开发经验分享(三)问题解决篇(中)
    EntityModelStudio系列教程4静态建模进阶
    EntityModelStudio系列教程6EMLib框架之Orm
  • 原文地址:https://www.cnblogs.com/cuish/p/3868544.html
Copyright © 2011-2022 走看看