Linux C++ 055-设计模式之状态模式

Linux C++ 055-设计模式之状态模式

本节关键字:Linux、C++、设计模式、状态模式

相关库函数:

概念

状态模式(State Pattern)是设计模式的一种,属于行为模式。允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

状态模式解决对象行为依赖于其状态的问题,使得对象可以在状态变化时切换行为。

优缺点

优点

1、封装状态转换规则:将状态转换逻辑封装在状态对象内部。

2、易于扩展:增加新的状态类不会影响现有代码。

3、集中状态相关行为:将所有与特定状态相关的行为集中到一个类中。

4、简化条件语句:避免使用大量的条件语句来切换行为。

5、状态共享:允许多个上下文对象共享同一个状态对象。

缺点

1、增加类和对象数量:每个状态都需要一个具体的状态类。

2、实现复杂:模式结构和实现相对复杂。

3、开闭原则支持不足:增加新状态或修改状态行为可能需要修改现有代码。

使用场景

1、一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。

2、一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

当对象的行为随状态改变而变化时,考虑使用状态模式。状态模式适用于替代复杂的条件或分支语句。

角色说明

状态模式包含以下几个主要角色:

上下文(Context):定义了客户感兴趣的接口,并维护一个当前状态对象的引用。上下文可以通过状态对象来委托处理状态相关的行为。

状态(State):定义了一个接口,用于封装与上下文相关的一个状态的行为。

具体状态(Concrete State):实现了状态接口,负责处理与该状态相关的行为。具体状态对象通常会在内部维护一个对上下文对象的引用,以便根据不同的条件切换到不同的状态。

代码示例

cpp 复制代码
//头文件
#include <iostream>
using namespace std;

class Context;
// 抽象出来的状态类
class State
{
public:
    /* 抽象的接口,每个子类去实现这个接口
       根据自己的逻辑执行任务或者转换状态。
    */
    virtual void Handle(Context *context) = 0;
    // 获得当前的状态
    virtual void GetState() = 0;
};

// 状态管理类
class Context
{
public:
    // 初始化状态
    Context(State *state) {
        m_pState = state;
    }
    // 获得当前的状态
    State* GetState() {
        return m_pState;
    }
    // 改变当前的状态
    void SetState(State *state)
    {
        m_pState = state;
    }
    // 执行状态类实现的方法
    void Request() {
        m_pState->Handle(this);
    }
    State* m_pState;
};
// 具体的状态子类
class ConcreteStateA:public State
{
public:
    void Handle(Context *context);
    void GetState();
};
// 具体的状态子类
class ConcreteStateB:public State
{
public:
    void Handle(Context *context);
    void GetState();
};
// 具体的状态子类
class ConcreteStateC:public State
{
public:
    void Handle(Context *context);
    void GetState();
};

// cpp文件
#include "StateMode.h"
void ConcreteStateA:: Handle(Context *context)
{
    context->m_pState = new ConcreteStateB;
    cout<<"当前状态是A,下一状态是B"<<endl;
}
void ConcreteStateB:: Handle(Context *context)
{
    context->m_pState = new ConcreteStateC;
    cout<<"当前状态是B,下一状态是C"<<endl;
}
void ConcreteStateC:: Handle(Context *context)
{
    context->m_pState = new ConcreteStateA;
    cout<<"当前状态是C,下一状态是A"<<endl;
}
void ConcreteStateA:: GetState()
{
    cout<<"当前状态是A"<<endl;
}
void ConcreteStateB:: GetState()
{
    cout<<"当前状态是B"<<endl;
}
void ConcreteStateC:: GetState()
{
    cout<<"当前状态是B"<<endl;
}
int main(int argc, char *argv[])
{
    // 初始化A状态
    Context* context = new Context(new ConcreteStateA);
    context->Request();
    context->Request();
    context->Request();
    getchar();
    return 0;
}
相关推荐
千里镜宵烛5 分钟前
C++ 红黑树
java·开发语言·c++
敲上瘾9 分钟前
高并发内存池(五):性能测试与性能优化
c++·功能测试·缓存·性能优化·线程·高并发内存池
小茬粥10 分钟前
COLT_CMDB_linux_processInfo.sh
linux·运维·chrome
愚润求学14 分钟前
【C++11】包装器:function 和 bind
开发语言·c++·笔记·c++11
珹洺19 分钟前
C++从入门到实战(十一)详细讲解C/C++语言中内存分布与C与C++内存管理对比
c语言·数据结构·c++
是店小二呀28 分钟前
【优选算法 | 前缀和】前缀和算法:高效解决区间求和问题的关键
android·c++·算法
BS_Li30 分钟前
C++类和对象(中)
开发语言·c++·类和对象
XiaoCCCcCCccCcccC32 分钟前
Linux中线程池的简单实现 -- 线程安全的日志模块,策略模式,线程池的封装设计,单例模式,饿汉式单例模式,懒汉式单例模式
linux·c语言·c++·安全·单例模式·策略模式
南玖yy41 分钟前
C++ 的未来战场:从技术深耕到职业破局
c语言·开发语言·c++·后端·c++未来
Cuit小唐43 分钟前
C++好用的打印日志类
开发语言·c++·算法