ライブラリとして設計されたC++で有限状態マシンを書いています。さらに、ライブラリで発生する状態の変化に応じてユーザーインターフェイスを更新する必要がある別のプロジェクトとして実装されたGUIがあります。
ここで通信を実装する方法は、GUIがライブラリ関数を呼び出し、有限状態マシンの状態に関する情報(およびその他の必要な情報)を含む構造体を返すことです。
しかし、これはかなりアドホックな解決策であると私は思います。それは頻繁な状況のように思われるので、これを処理するデザインパターン/テキストブックの方法があるかどうか知りたいです。
最も簡単な方法は、状態が変化した(または他のイベントが発生した)ときに呼び出されるコールバック関数を状態マシンに渡すことです。
次に、それが呼び出されたときに、その関数のGUIを更新できます(または、状態マシンが別のスレッドで実行されている場合は、メッセージをGUIスレッドに転送します)。
署名はvoid callback(State oldstate, State newstate, void* userData)
のようなものになります
userData
ポインターは、関数ポインターと同時に提供され、(静的)コールバック関数のコンテキストを提供します。必要に応じて、std::Function
代わりに、関数pointer + userDataメソッドをオーバーロードとして保持します。
GUIライブラリ(Qtなど)は、イベントベースのサブスクライバーパブリッシャーデザインパターンを使用しています。つまり、イベントでは、すべてのサブスクライバーに通知されます。
したがって、状態が変化したら、イベントを公開します。イベントをサブスクライブしたすべてのオブジェクトは、コールバックを実行します。
Observerパターンは、GUIを更新するためのシンプルでクリーンなソリューションだと思います。
これは、システムのようなイベントを実装できるようにする動作パターンです。これにより、GUIがライブラリから適切に切り離されます。
私は通常、他のアダプターパターンと組み合わせて使用して、メインのエンティティから具体的な「更新」実装を分離します。このようにして、IObserverから継承することなく、さまざまな更新動作を混合して一致させることができます
https://en.wikipedia.org/?title=Observer_pattern
「コールバック」実装よりも優れている点は次のとおりです。
たとえば、それを使用してGUIを更新したり、ファイルやその他のログに記録したりすることができます。これらはすべて個別のスレッドで行われます。