它本身是实现状态机的非常好的模式,因为它允许将状态转换逻辑封装在状态本身中,并且添加新状态实际上变得更容易,因为您只需要在相关状态中进行更改。
但是,在描述状态应该如何改变时通常会避免。
如果你在 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/