• (三)行为模式:8、状态模式(State Pattern)(C++示例)


    目录

    1、状态模式(State Pattern)含义

    2、状态模式的UML图学习

    3、状态模式的应用场景

    4、状态模式的优缺点

    (1)优点

    (2)缺点

    5、C++实现状态模式的实例


    1、状态模式(State Pattern)含义

    状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。【DP】

    状态模式主要解决的是,当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。当然,如果这个状态判断很简单,那就没必要用‘状态模式’了 。“

    2、状态模式的UML图学习

    状态模式主要涉及以下几个角色:

    (1)环境(Context):环境类是拥有状态的对象,它维护一个对抽象状态类的引用,通过该引用来切换当前状态。环境类在其操作中会委托给当前状态对象进行处理。

    (2)抽象状态(State):抽象状态类定义了一个接口,用于封装环境对象的特定状态所对应的行为。

    (3)具体状态(Concrete State):具体状态类实现了抽象状态类定义的接口,并根据具体情况进行相应的处理和状态转换。

    通过这些角色的协作,状态模式可以实现对象的状态与行为之间的解耦,使得状态的变化不会影响到客户端代码,同时也方便了状态的扩展和维护。

    3、状态模式的应用场景

    (1)一个对象的行为取决于它的状态,并且需要在运行时根据状态改变行为时,可以考虑使用状态模式。

    (2)当一个对象的行为在不同的状态下有不同的实现,且这些状态可以动态切换时,可以考虑使用状态模式。

    (3)当需要消除大量的条件判断语句,并将其转换为状态类之间的关联时,可以考虑使用状态模式。

    4、状态模式的优缺点

    (1)优点

            1)将状态转换逻辑封装在具体的状态类中,使得状态变化对于客户端来说是透明的,客户端无需关心状态的切换细节。

            2)将大量的条件判断语句转换为状态类之间的关联,使得代码更加清晰、可读性更高。

            3)符合开闭原则,当需要增加新的状态时,只需要添加新的状态类而不需要修改现有的代码。

    简而言之:"是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来【DP】"

    (2)缺点

            1)状态模式会引入多个状态类,增加了系统的复杂性。 

            2)如果状态转换比较复杂,可能会导致状态类之间的相互调用增多,影响系统的性能。

    5、C++实现状态模式的实例

    1. #include
    2. // 状态接口
    3. class State
    4. {
    5. public:
    6. virtual void handle() = 0;
    7. };
    8. // 具体状态类A
    9. class ConcreteStateA : public State
    10. {
    11. public:
    12. void handle() override
    13. {
    14. std::cout << "Handle by ConcreteStateA" << std::endl;
    15. }
    16. };
    17. // 具体状态类B
    18. class ConcreteStateB : public State
    19. {
    20. public:
    21. void handle() override
    22. {
    23. std::cout << "Handle by ConcreteStateB" << std::endl;
    24. }
    25. };
    26. // 上下文类
    27. class Context
    28. {
    29. private:
    30. State* state;
    31. public:
    32. Context(State* initialState) : state(initialState) {}
    33. void setState(State* newState)
    34. {
    35. state = newState;
    36. }
    37. void request()
    38. {
    39. state->handle();
    40. }
    41. };
    42. int main() {
    43. // 创建状态对象
    44. State* stateA = new ConcreteStateA();
    45. State* stateB = new ConcreteStateB();
    46. // 创建上下文对象并设置初始状态
    47. Context context(stateA);
    48. // 请求处理
    49. context.request(); // 输出: Handle by ConcreteStateA
    50. // 切换状态
    51. context.setState(stateB);
    52. context.request(); // 输出: Handle by ConcreteStateB
    53. // 释放资源
    54. delete stateA;
    55. delete stateB;
    56. return 0;
    57. }

    上述示例中,定义了一个状态接口State,具体状态类ConcreteStateAConcreteStateB实现了该接口。上下文类Context持有一个状态对象,并根据当前状态调用相应的行为。通过切换状态,可以改变上下文对象的行为。

  • 相关阅读:
    SHIB去零计划:创新金融未来,打造稳定数字资产新范式
    SpringBoot项目启动时预加载
    centos 8.2 配置 go 项目开发环境
    Matlab求各种类型数组长度的方法
    解决kkFileView4.4.0版本pdf、word不能预览问题
    Java内存溢出(OOM)分析
    AOP基础知识了解
    Nvidia Jetson Nano学习笔记--使用C语言实现GPIO 输入输出
    Modelsim测试覆盖率操作说明
    从头开始,手写android应用框架(一)
  • 原文地址:https://blog.csdn.net/bigger_belief/article/details/132414208