【设计模式】状态

状态,应该大家都很熟,学过计算机的应该都知道状态机。

状态实现比较简单,当然也比较灵活。写一个demo程序,测试一下而已,主要是状态和策略两个模式很相似,想体会一下其中的区别。

状态一般也要求状态是一个单例,否则状态的生成和回收还是比较繁琐的。

1. State.h:

#include <iostream>
using namespace std;

class Context;
class State{
public:
    State(){}
    ~State(){};
    virtual int Handle(Context * ctxt) = 0;
};

class Context{
public:
    Context(){
        state = NULL;
    }
    int Handle(){
        if (state){
            state->Handle(this);
        } else {
            cout<<"NULL state!"<<endl;
        }
        return 0;
    }
    int change_state(State * new_state){
        state = new_state;
        return 0;
    }
private:
    State * state;
};
2. StateA.h/StateA.cpp

#ifndef  __STATEA_H_
#define  __STATEA_H_

#include "State.h"
#include "StateB.h"
class StateA : public State{
public:
    static StateA * Instance();
    int Handle(Context * ctxt);
    ~StateA(){}
private:
    StateA(){}
    static StateA * instance;
};

#endif  //__STATEA_H_

#include "StateA.h"
class StateB;
StateA * StateA::instance = NULL;
StateA * StateA::Instance(){
    if (!instance){
        instance = new StateA();
    }
    return instance;
}

int StateA::Handle(Context * ctxt){
  cout<<"handle state A: A=>B!"<<endl;
  ctxt->change_state(StateB::Instance());
  return 0;
}

3. StateB.h/.cpp
#ifndef  __STATEB_H_
#define  __STATEB_H_

#include "State.h"
#include "StateA.h"
class StateB : public State{
public:
    ~StateB(){}
    static StateB * Instance();
    
    int Handle(Context * ctxt);
private:
    StateB(){}
    static StateB * instance;
};

#endif  //__STATEB_H_
#include "StateB.h"
StateB * StateB::instance = NULL;
StateB * StateB::Instance(){
    if (!instance){
        instance = new StateB();
    }
    return instance;
}

int StateB::Handle(Context * ctxt){
    cout<<"handle state B: B=>A!"<<endl;
    ctxt->change_state(StateA::Instance());
    return 0;
}

4. test

#include <iostream>
#include "StateA.h"
#include "StateB.h"
using namespace std;

int main(){
    Context * ctxt = new Context();
    ctxt->change_state(StateA::Instance());
    ctxt->Handle();
    ctxt->Handle();
    ctxt->Handle();
    return 0;
}

这里为了写个测试程序还搞了很多*.h*.cpp文件,主要是因为交叉包含问题。这个感觉很挫,不知道新的编译器或者标准有没有改进。


总结,state模式比较简单,使用场合也比较明确。很多时候都不需要抽象出具体的state,直接通过应用场景相关的类代替即可,因为,问题的关键不是模板,而是不同状态下的动作和状态转移关系。

另外,context要暴露状态转换接口方式有点繁琐,感觉也比较危险。但是还没想到有什么好的解决方案。




状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态发生改变时改变它的行为。该模式的核心思想是封装对象的状态,使得它对外部的影响最小化。状态模式常常被应用于需要按照状态决定行为的场合,比如状态机、游戏状态等。 在状态模式中,我们通常会定义一个抽象状态类(Abstract State)和若干个具体状态类(Concrete State),每个具体状态类表示对象在不同状态下的行为。同时,我们还需要定义一个环境类(Context),它包含了一个状态对象,负责状态的切换和行为的调用。 状态模式的优点包括: 1. 状态模式将状态的处理分散在不同的状态类中,使得每个状态类只需处理自己状态下的行为,降低了代码的复杂度和耦合度。 2. 状态模式将状态和行为分离,使得对象的状态可以在运行时动态改变,而不需要改变对象自身的结构。 3. 状态模式符合“开闭原则”,容易扩展和增加新的状态和行为。 但是,状态模式也存在一些缺点,包括: 1. 状态模式会导致类的数量增加,其中每个状态都需要一个具体状态类,这可能会导致类的爆炸。 2. 状态模式会增加代码的复杂度,尤其是当状态之间的转换比较复杂时。 总之,状态模式是一种非常有用的设计模式,它可以让对象状态的变化更加灵活和可控。但是,在实际应用过程中,我们需要权衡其优缺点,选择合适的使用场景和实现方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值