状态模式

Posted alvin2010

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状态模式相关的知识,希望对你有一定的参考价值。

1、状态模式定义

  状态对象:在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之发生变化。

  状态模式(State Pattern) :类的行为是基于它的状态改变的。状态模式的别名为状态对象(Objects for States)。

2、状态模式结构

  状态模式包含如下角色:

  • Context: 环境类
  • State: 抽象状态类
  • ConcreteState: 具体状态类

  技术分享图片

3、状态模式的实现

  这里我们以程序员上班工作为例,状态分为 上午,中午,下午和晚上。

#ifndef STATE_H_
#define STATE_H_
#include <cstdio>

//
class State;

class Work
{
private:
    State* state_;
    int hour_;
public:
    Work();
    ~Work();

    void SetHour(int hour);
    int GetHour();

    void SetState(State* state);
    State* GetState();

    void WriteProgram();
};


class State
{
public:
    virtual void WriteProgram(Work* work) {};
    virtual ~State(){} 
};


class ForenoonState : public State
{
public:
    void WriteProgram(Work* work);
};


class NoonState : public State
{
public:
    void WriteProgram(Work* work);
};


class AfternoonState : public State
{
public:
    void WriteProgram(Work* work);
};


class EveningState : public State
{
public:
    void WriteProgram(Work* work);
};


class SleepingState : public State
{
public:
    void WriteProgram(Work* work);
};


class RestState :public State
{
public:
    void WriteProgram(Work* work)
    {
        printf("Rest state
");
    }
};

#endif

 

  

#include "state.h"


Work::Work()
{
    state_ = new ForenoonState();
}

Work::~Work()
{
    if (state_ != NULL)
    {
        delete state_;
    }
}

void Work::SetHour(int hour)
{
    hour_ = hour;
}

int Work::GetHour() { return hour_; }

void Work::SetState(State* state)
{
    state_ = state;
}

State* Work::GetState() { return state_; }


void Work::WriteProgram()
{
    state_->WriteProgram(this);
}


void ForenoonState::WriteProgram(Work* work)
{
    if (work->GetHour() < 12)
    {
        printf("forenoon work state
");
    }
    else
    {
        State* sta = work->GetState();
        delete sta;
        work->SetState(new NoonState());
        work->WriteProgram();
    }
}


void NoonState::WriteProgram(Work* work)
{
    if (work->GetHour() < 13)
    {
        printf("noon work state
");
    }
    else
    {
        State* sta = work->GetState();
        delete sta;
        work->SetState(new AfternoonState());
        work->WriteProgram();
    }
}


void AfternoonState::WriteProgram(Work* work)
{
    if (work->GetHour() < 17)
    {
        printf("AfternoonState work state
");
    }
    else
    {
        State* sta = work->GetState();
        delete sta;
        work->SetState(new EveningState());
        work->WriteProgram();
    }
}


void EveningState::WriteProgram(Work* work)
{
    if (work->GetHour() < 21)
    {
        printf("EveningState work state
");
    }
    else
    {
        State* sta = work->GetState();
        delete sta;
        work->SetState(new SleepingState);
        work->WriteProgram();
    }
}


void SleepingState::WriteProgram(Work* work)
{
    if (work->GetHour() < 22)
    {
        printf("Sleeping state
");
    }
    else
    {
        State* sta = work->GetState();
        delete sta;
        work->SetState(new RestState());
        work->WriteProgram();
    }
}

 

4、状态模式的优缺点

  1、枚举可能的状态,在枚举状态之前需要确定状态种类

  2、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

5、状态模式的使用环境

  状态模式可以适用于条件状态多但可以通过穷举法列出所有情况的开发模式中,典型的应用就是TCP三次握手的状态转换、游戏中状态装换和办公系统的处理状态等等。

 

以上是关于状态模式的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段13——Vue的状态大管家

VSCode自定义代码片段13——Vue的状态大管家

方向/配置更改后如何维护 ListView 片段状态?

java BottomBarNavigation代码保留片段状态

为不同方向使用不同布局时,在方向更改时保存片段状态

多选模式列表视图行在删除后保持选中状态