餐馆那些事之:State Pattern

1. 概述
State Pattern即状态模式。一个简单的case:
对于自动门来说,有两种状态:open和close,如果门处于open状态,如果用户再按open按钮,没有反应,如果按下close键,则门关闭。
switch...case...实现:
const int OPEN = 1; // door  open 状态
const int CLOSE = 2;// door close 状态
class Manage
{
public:
void open()
{
   switch(door.state)
   {
      case OPEN : 
                do nothing;
                 break;
      case CLOSE: 
                open the door;
                 break;
      default:
                 break;
    }
}
}
可以看到,状态及相应的操作都由Manage类来管理,状态和相应操作没有隔离,无法独立变化;此外,如果状态过多,会带来Manage类代码过于复杂的问题。
为此,引入State Pattern,主要应用于:
1)一个对象的行为取决于它的状态的场景。
2)有限状态自动机

state的类图:

Manage:对client提供服务接口
State:状态抽象基类
State_x:具体状态类,定义该状态下相应操作的具体行为
有一个非常重要的点,状态迁移由谁来控制,两种方案:
1)由Manage类来负责状态迁移
2)State类本身负责状态迁移
前者的缺点在于增加新的状态类较复杂,如果状态过多,状态迁移负责,会带来Manage类过于复杂,此外,Manage类需要了解具体的状态类
后者的缺点在于各个state对象必须知晓其兄弟state对象的存在,为此带来了state子类之间的依赖。

2. 例子

餐馆Waiter有两种状态:busyness和idle,如果Waiter正在忙碌,则无法响应客人的服务请求,如果正处于Idle状态,则可以响应客人的请求,并把自己的状态置为Busyness
State Pattern实现方法(state子类负责状态迁移)
#include <iostream>

using namespace std;

class Waiter
{
public:
        Waiter();

        void request();

        void setCur(class State* state)
        {
                _cur = state;
        }

private:
        State *_cur;
};

class State
{
public:
        virtual ~State()
        {
        }

        virtual void request(Waiter*) = 0;
};

class Busyness_state : public State
{
public:
        void request(Waiter*)
        {
                cout << "Waiter: i am busy, boss" << endl;
        }
};


class Idle_state : public State
{
public:
        void request(Waiter* waiter)
        {
                cout << "Waiter: i am coming" << endl;
                waiter->setCur(new Busyness_state);
                cout << "Waiter state change from idle to business" << endl;
                delete this;
        }
};

Waiter::Waiter()
{
        _cur = new Idle_state();
}

void Waiter::request()
{
        cout << "Client: service request" << endl;
        _cur->request(this);
}

int main()
{
        Waiter waiter;
        waiter.request();
        waiter.request();
        waiter.request();

        return 0;
}
输出:
Client: service request
Waiter: i am coming
Waiter state change from idle to business
Client: service request
Waiter: i am busy, boss
Client: service request
Waiter: i am busy, boss

State Pattern实现2(Manage负责状态迁移)
#include <iostream>
#include <vector>

using namespace std;

class Waiter
{
public:
        Waiter();

        void request();

        void setCur(class State* state)
        {
                if(_cur)
                {
                        delete _cur;
                }
                _cur = state;
        }

private:
        State *_cur;
};

class State
{
public:
        virtual ~State()
        {
        }

        virtual bool request() = 0;
};

class Busyness_state : public State
{
public:
        bool request()
        {
                cout << "Waiter: i am busy, boss" << endl;
                return false;
        }
};


class Idle_state : public State
{
public:
        bool request()
        {
                cout << "Waiter: i am coming" << endl;
                return true;
        }
};

Waiter::Waiter()
{
        _cur = new Idle_state();
}

void Waiter::request()
{
        cout << "Client: service request" << endl;
        if(_cur->request())
        {
                setCur(new Busyness_state);
                cout << "Waiter state change from idle to business" << endl;
        }
        else
        {
                cout << "Waiting....." << endl;
        }

}

int main()
{
        Waiter waiter;
        waiter.request();
        waiter.request();
        waiter.request();

        return 0;
}
输出:
Client: service request
Waiter: i am coming
Waiter state change from idle to business
Client: service request
Waiter: i am busy, boss
Waiting.....
Client: service request
Waiter: i am busy, boss
Waiting.....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值