C++设计模式--状态模式(state)

版权声明:支持原创,转载请说明~ https://blog.csdn.net/luoyayun361/article/details/88072290

概述

前面文章介绍了代理模式(在这里),代理模式和状态模式都提供一个代理类,从结构上看,可以认为代理模式只是状态模式的一个特例,不同之处在于,代理模式控制对其实现类的访问,而状态模式动态地改变其实现类,当发现大多数或者所有函数都存在条件代码时,这种模式很有用。

状态模式

简单来说,状态模式通过一个前端对象来使用后端实现对象履行其职责,在前端对象生存期期间,状态模式从一个实现对象到另一个实现对象进行切换,以实现对于相同的函数调用产生不同的行为。

示例:

#include <iostream>

using namespace std;

class Creature
{
public:
    Creature():isFrog(true) {}
    void kiss(){isFrog = false;}
    void greet(){
        if(isFrog){
            cout << "Ribbet!" << endl;
        }
        else{
            cout << "Dearling!" << endl;
        }
    }

private:
    bool isFrog;
};

int main()
{
    Creature creature;
    creature.greet();
    creature.kiss();
    creature.greet();
    return 0;
}

从上述代码可以看到,greet()等任何其他所有函数在执行操作前都必须测试变量 isFrog,这样让代码变得非常笨拙,特别是在系统中加入额外的状态时情况会更加严重。

接下来我们通过状态模式来修改以上示例,将操作委派给状态对象:


#include <iostream>

using namespace std;

class Creature
{
private:
    class State
    {
    public:
        virtual string response() = 0;
        virtual ~State();
    };
    class Frog : public State
    {
    public:
        string response(){return "Ribbet!";}
        virtual ~Frog();
    };
    class Prince : public State
    {
    public:
        string response(){return "Daring!";}
        virtual ~Prince();
    };
    State * state;

public:
    Creature():state(new Frog()){}
    void greet(){
        cout << state->response() << endl;
    }
    void kiss(){
        delete state;
        state = new Prince();
    }
};

int main()
{
    Creature creature;
    creature.greet();
    creature.kiss();
    creature.greet();
    return 0;
}

(这里为了简单,使用了类嵌套定义,可以不必这样做)

适用场景

在下面两种情况下均可以使用状态模式:

1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为;
2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。State 模式将每一个条件分支放入一个独立的类中。这使得你可以根据自身情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

猜你喜欢

转载自blog.csdn.net/luoyayun361/article/details/88072290