zoukankan      html  css  js  c++  java
  • 【设计模式】 状态模式

    1、定义

    1.1 标准定义

      其定义如下:
      Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.(当一个对象内在状态改变时允许其改变行为, 这个对象看起来像改变了其类。)

      状态模式的核心是封装, 状态的变更引起了行为的变更, 从外部看起来就好像这个对象对应的类发生了改变一样。

    1.2 通用类图

      ● State——抽象状态角色
      接口或抽象类, 负责对象状态定义, 并且封装环境角色以实现状态切换。

      ● ConcreteState——具体状态角色
      每一个具体状态必须完成两个职责: 本状态的行为管理以及趋向状态处理, 通俗地说,就是本状态下要做的事情, 以及本状态如何过渡到其他状态。

      ● Context——环境角色
      定义客户端需要的接口, 并且负责具体状态的切换。

    2、实现

    2.1 类图

      Context:定义客户端感兴趣的接口,并且维护一个ConcreteState子类的实例,这个实例定义当前状态;
      State:定义一个接口以封装与Context的一个特定状态相关的行为;
      ConcreteState subclasses:每一个子类实现一个与Context的一个状态相关的行为。

    2.2 代码

    #include <iostream>
    using namespace std;
    
    class Context;
    
    class State
    {
    public:
       // 状态处理,此处可以选择是否切换到其他状态
    virtual void Handle(Context *pContext) = 0; }; class ConcreteStateA : public State { public: virtual void Handle(Context *pContext) { cout<<"I am concretestateA."<<endl; } }; class ConcreteStateB : public State { public: virtual void Handle(Context *pContext) { cout<<"I am concretestateB."<<endl; } }; class Context { public: Context(State *pState) : m_pState(pState){} void Request() { if (m_pState) { m_pState->Handle(this); } } void ChangeState(State *pState) { m_pState = pState; } private: State *m_pState; }; int main() { State *pStateA = new ConcreteStateA(); State *pStateB = new ConcreteStateB(); Context *pContext = new Context(pStateA); pContext->Request(); pContext->ChangeState(pStateB); pContext->Request(); delete pContext; delete pStateB; delete pStateA; }

    3、总结

    3.1 优点

      ● 结构清晰
      避免了过多的switch...case或者if...else语句的使用, 避免了程序的复杂性,提高系统的可维护性。

      ● 遵循设计原则
      很好地体现了开闭原则和单一职责原则, 每个状态都是一个子类, 你要增加状态就要增加子类, 你要修改状态, 你只修改一个子类就可以了。

      ● 封装性非常好
      这也是状态模式的基本要求, 状态变换放置到类的内部来实现, 外部的调用不用知道类内部如何实现状态和行为的变换。

    3.2 缺点

      状态模式既然有优点, 那当然有缺点了。 但只有一个缺点, 子类会太多, 也就是类膨胀。 

    3.3 使用场景

      ● 行为随状态改变而改变的场景
      这也是状态模式的根本出发点, 例如权限设计, 人员的状态不同即使执行相同的行为结果也会不同, 在这种情况下需要考虑使用状态模式。

      ● 条件、 分支判断语句的替代者
      在程序中大量使用switch语句或者if判断语句会导致程序结构不清晰, 逻辑混乱, 使用状态模式可以很好地避免这一问题, 它通过扩展子类实现了条件的判断处理。

    3.4 注意事项

      状态模式适用于当某个对象在它的状态发生改变时, 它的行为也随着发生比较大的变化, 也就是说在行为受状态约束的情况下可以使用状态模式, 而且使用时对象的状态最好不要超过5个。 

  • 相关阅读:
    luogu P2472 [SCOI2007]蜥蜴 网络流 拆点
    luogu P2762 太空飞行计划问题 网络流24
    luogu P2774 方格取数问题 网络流24 最小割
    luogu P2766 最长不下降子序列问题 网络流24
    Codeforces Round #651 (Div. 2) E
    Codeforces Round #651 (Div. 2) D
    Codeforces Round #651 (Div. 2) C
    Codeforces Global Round 8 E
    Codeforces Global Round 8 D
    【最小生成树】Truck History POJ
  • 原文地址:https://www.cnblogs.com/ChinaHook/p/7309215.html
Copyright © 2011-2022 走看看