web-dev-qa-db-ja.com

ステートマシン:どのオブジェクトが状態の転送を担当しますか?

ステートマシンを作りたいのですが。

Stateにはrunメソッドがあり、いくつかのロジックによれば、次の状態を設定します。


  • オプション1:

各状態が次の状態を決定する責任がある場合、それはnext_state()を持ち、ポインターまたは他のいくつかの状態のIDを返すため、各状態に他の状態の存在を知らせるよう強制します== >悪い。

  • オプション2:

他のエンティティが次の状態を担当している場合、いくつかのロジックは次の状態を計算する必要がありますが、現在の状態に依存するため、現在の状態のカプセル化が解除されます(またはゲッターのようなメソッドを強制的に作成すると、実際にはオプション1)==>悪い


したがって、次のステップを決定するステートマシンの部分のカプセル化を壊さない方法を思いつくことはできません。

Wikipediaでも はこれに光を当てないので、この場合のベストプラクティスを聞きたいと思います。

2
Gulzar

抽象化全体で複数のオブジェクトが必要になる場合があります。

GoF状態パターンは非常に一般的な目的です。各状態は、後継者の状態についてのみ知る必要があるため、後継者状態に移行できます。各状態はクラスであるため、状態をサブクラス化できます(階層状態マシンの場合)。状態は互いに独立したインスタンス変数を持つことができ、状態は動的に作成されるため、それらのインスタンス変数は、その状態にある間だけ適切な存続期間を持ちます。


ただし、これらの要件がない場合は、単一のクラスステートマシンで十分です。単純なステートマシンで、1つのクラス内のコンテキスト(現在の状態)と遷移をキャプチャし、列挙型だけで状態を記述できます。


重要なことは、消費するクライアントにとって、ステートマシンが外部からどのように見えるかです。これにより、内部実装はGoFマルチクラスアプローチ、またはより単純またはより複雑なものを使用できます。

4
Erik Eidt