23种设计模式(十七)状态变化之状态模式

    科技2022-08-06  107

    本系列所有文章来自李建忠老师的设计模式笔记,系列如下: 设计模式(一)面向对象设计原则 23种设计模式(二)组件协作之模板方法 23种设计模式(三)组件协作之策略模式 23种设计模式(四)组件协作之观察者模式 23种设计模式(五)单一职责之装饰模式 23种设计模式(六)单一职责之桥模式 23种设计模式(七)对象创建之工厂方法 23种设计模式(八)对象创建之抽象工厂 23种设计模式(九)对象创建之原型模式 23种设计模式(十)对象创建之构建器 23种设计模式(十一)对象性能之单件模式 23种设计模式(十二)对象性能之享元模式 23种设计模式(十三)接口隔离之门面模式 23种设计模式(十四)接口隔离之代理模式 23种设计模式(十五)接口隔离之适配器 23种设计模式(十六)接口隔离之中介者 23种设计模式(十七)状态变化之状态模式 23种设计模式(十八)状态变化之备忘录 23种设计模式(十九)数据结构之组合模式 23种设计模式(二十)数据结构之迭代器 23种设计模式(二十一)数据结构之职责链 23种设计模式(二十二)行为变化之命令模式 23种设计模式(二十三)行为变化之访问器 23种设计模式(二十四)领域规则之解析器

    文章目录

    动机设计方法一设计方法二模式定义要点总结

      在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?”状态变化“模式为这一问题提供了一种解决方案。

    动机

      在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。

    设计方法一

      假设有一个网络操作的功能,有三种状态:打开、关闭、连接。每种状态下的功能不一样。

    state1.cpp enum NetworkState { Network_Open, Network_Close, Network_Connect, }; class NetworkProcessor{ NetworkState state; public: void Operation1(){ if (state == Network_Open){ //********** state = Network_Close; } else if (state == Network_Close){ //.......... state = Network_Connect; } else if (state == Network_Connect){ //$$$$$$$$$$ state = Network_Open; } } public void Operation2(){ if (state == Network_Open){ //********** state = Network_Connect; } else if (state == Network_Close){ //..... state = Network_Open; } else if (state == Network_Connect){ //$$$$$$$$$$ state = Network_Close; } } public void Operation3(){ } };

      上述这种设计方法当有新的枚举类型添加的话,需要改动的地方就比较多了。

    设计方法二

    state2.cpp class NetworkState{ public: NetworkState* pNext; virtual void Operation1()=0; virtual void Operation2()=0; virtual void Operation3()=0; virtual ~NetworkState(){} }; class OpenState :public NetworkState{ static NetworkState* m_instance; public: static NetworkState* getInstance(){ if (m_instance == nullptr) { m_instance = new OpenState(); } return m_instance; } void Operation1(){ //********** pNext = CloseState::getInstance(); } void Operation2(){ //.......... pNext = ConnectState::getInstance(); } void Operation3(){ //$$$$$$$$$$ pNext = OpenState::getInstance(); } }; class CloseState:public NetworkState{ } //... class NetworkProcessor{ NetworkState* pState; public: NetworkProcessor(NetworkState* pState){ this->pState = pState; } void Operation1(){ //... pState->Operation1(); pState = pState->pNext; //... } void Operation2(){ //... pState->Operation2(); pState = pState->pNext; //... } void Operation3(){ //... pState->Operation3(); pState = pState->pNext; //... } };

      上述的这种方式其实用虚函数指针来去判断是Open态还是Close态还是Connect态。

      当有新的状态来的话,我们只需要扩展子类即可。

    模式定义

      允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。

    要点总结

      State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。

      为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的–即要么彻底转换过来,要么不转换。

      如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。

    Processed: 0.033, SQL: 8