2017-08-21 32 views
0

state pattern避免公众`SETSTATE()在C++`状态接口模式实现

Class diagram

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

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

如果您在Context中实现了状态更改逻辑,那么整个模式点都会丢失,但是如果您在状态中实现状态更改逻辑,那意味着您需要在Context中设置新状态。

最常见的方式是将公共方法添加到ContextSetState()并通过参考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 { ... }; 
} 

但总的来说改变派生类中的方法范围不看起来非常好。

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

+0

在C++中,FSM最好通过模板元编程实现。 Boost :: MPL虽然有些过时,但提供了一个示例:http://www.boost.org/doc/libs/1_31_0/libs/mpl/doc/paper/html/example.html – SergeyA

+0

使用std :: variant和visit对于状态机也提供了一些显着的优点。但这个问题的答案超出了范围。 –

回答

1

你可以考虑具有处理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. 
     } 
}; 
0

状态模式的目标是隐藏/从caller.However封装不同的实现方式,调用者只需要知道什么它需要的实施类型。