c++ - 在 C++ 的状态模式实现中避免公共(public) `SetState()` 接口(interface)

标签 c++ c++11 state-pattern

state pattern

Class diagram

它本身是实现状态机的非常好的模式,因为它允许将状态转换逻辑封装在状态本身中,并且添加新状态实际上变得更容易,因为您只需要在相关状态中进行更改。

但是,在描述状态应该如何改变时通常会避免。

如果你在 Context 中实现状态改变逻辑,那么整个模式的要点就被遗漏了,但是如果你在 states 中实现状态改变逻辑,这意味着你需要在 中设置一个新的状态上下文

最常见的方法是将公共(public)方法添加到 Context SetState() 并将对 Context 的引用传递给状态对象,因此它将能够设置一个新状态,但本质上它将允许用户在状态机之外更改状态。

为了避免这种情况,我采用了以下解决方案:

class IContext {
     public:
         virtual void SetState(unique_ptr<IState> newState) = 0;
}

class Context : public IContext {
     private:
         virtual void SetState(unique_ptr<IState> newState) override { ... };
}

但通常在派生类中更改方法范围看起来并不是很好。

是否有另一种方法来隐藏此接口(interface)( friend 类不是一个选项,因为它需要为每个添加的状态更改 Context 类)?

最佳答案

您可以考虑让处理程序handle()返回下一个状态...

class IState {
     public:
         virtual unique_ptr<IState> handle(Context&) = 0;
};

class StateA : public IState {
     private:
         // presented inline for simplicity, but should be in .cpp
         // because of circular dependency.
         //
         virtual unique_ptr<IState> handle(Context& ctx) override
         {
             //...
             if (/*...*/)
               return make_unique(StateB{});

             //...  including other state switch..

             return { nullptr };  // returning null indicates no state change, 
                                  // returning unique_ptr<>(this) is not really an option.
         }
};

关于c++ - 在 C++ 的状态模式实现中避免公共(public) `SetState()` 接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45800929/

相关文章:

php - 状态设计模式对于 PHP 表单是否过大?

c++ - Uncrustify 代码格式化程序删除了 C++ 单行代码中的空格

c++ - 如何在 vtk 中的 3D 表面渲染输出中获取 2D dicom 图像切片的位置

c++ - 声明引用在类中有效,但在主函数中无效

c++ - 状态模式 C++

java - 对状态模式的不理解

c++ - for循环计数器不增加

c++ - 如何从函数返回 std::optional<myclass>?

c++ - 类型特征检查类特殊函数的琐碎性的基本原理

c++ - 为什么以下 C++ 代码中存在内存泄漏?