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

概述

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

状态模式

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

示例:

#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 模式将每一个条件分支放入一个独立的类中。这使得你可以根据自身情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luoyayun361

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值