10

「ギャング オブ フォー」戦略であるクラスは、完全にステートレス (つまり、フィールドがない) である必要がありますか、それとも不変の状態 (つまり、最終フィールド) を含むことができますか?

4

5 に答える 5

18

戦略クラスは、物ではなくアクションをカプセル化します。したがって、本当に必要な場合は可能ですが、状態を保持することはあまり意味がありません。名詞ではなく動詞と考えてください。または、少なくともアクションを説明する名詞として。一方、いつでも戦略をパラメータ化し、クライアント オブジェクトの状態をメソッド呼び出しなどで渡すことができます。

また、クラスがステートレスかステートフルかは、finalそのフィールドのキーワードに実際には依存しません。例:

  • finalオブジェクトでのみ使用される場合、オブジェクトへの参照が変更されない可能性があることを意味します。フィールドなど、そのオブジェクトのコンテンツを変更することはできます。その場合、フィールドは final ですが、クラスはステートフルです。
  • フィールドが実際に定数である場合、ほとんどの意図と目的のために、ステートレスと見なすことができます。たとえば、フィールドprivate static finalを宣言してから、参照されるオブジェクトの状態を変更するために何もしないようにすることができます。

編集: 戦略自体のパラメーターと、その戦略の特定の実行のパラメーターを区別してみましょう。戦略クラスがステートレスである場合、そのクラスの複数のインスタンスを持つ意味がありません。これにより、クラスではなくオブジェクトがアクション自体を表し、メソッドの実行がその戦略の特定の実行を表すことになります。

ここで、ストラテジー自体のパラメーターがある場合、そのストラテジーのすべての実行に対してパラメーターが同じ値を持つことだけが理にかなっています。そのため、定数、定数を返すメソッド呼び出し (静的なものが必要ない場合) に配置することも、ハードコーディングすることもできます。上で説明したように、これはステートレスな方法で実装できます。

一方、パラメーターが戦略の 1 つの特定の実行を記述する場合は、それをパラメーターとしてメソッドに渡すだけです。それはします。

追記: '副詞' を状態に詰め込んだアクション オブジェクトを使用するのには十分な理由があります。たとえば、遅延やスケジューリングを伴う実行のある種のアクション キューが必要な場合です...そのためのパターンもあります - コマンド.

于 2011-05-30T13:35:01.090 に答える
5

ステートレスとは、戦略の実行間でデータが保持されないという事実を指します。つまり、同じストラテジーを 2 回実行すると、前のストラテジーの実行から何も引き継がれません。これは、必要に応じてストラテジーの実装を「リセット」する手間を省けるという点で有益です。

ストラテジー パターンの実装の説明では、ストラテジーが実行する必要があるデータを含むコンテキスト (@ 私の本の 317 ページ) を参照していることに注意してください。実装に必要なすべての「状態」は、おそらくこれらのコンテキスト オブジェクトに入るはずです。

これは、戦略の実装自体はステートレスであることを意味しますが、必要なデータがコンテキストで渡されるため、パターン全体として状態があります。

たとえば、算術演算の戦略を実装した場合、少なくとも 2 つの方法があります。1 つ目は、構築時に戦略の実装に arg1 と arg2 (および 3 と 4...) を設定することです。次に、実装を実行すると、そのフィールドが取得され、操作が実行されます。問題は、同じ実装を再度実行する場合、そのすべてのフィールドをリセットする (または新しい実装を作成する) 必要があることです。

2 番目の方法は、すべての引数を含むコンテキストを作成することです。戦略的な実装は、コンテキストから必要な値を取得します。次に、毎回新しいコンテキストを渡すだけで、戦略実装の各インスタンスを再利用できます。実装の新しいインスタンスを再作成したり、実装インスタンスのリセットを忘れたりする心配はありません。もちろん、コンテキストを正しく管理する必要があります。

于 2011-05-30T13:32:53.913 に答える
3

戦略パターンの目的は、メソッドのローカル スコープで直接戦略メソッドの引数を処理することです。もちろん、戦略クラス自体は必要に応じていくつかのフィールドを保持できますが、メソッドの引数をそれらのフィールドに割り当てないでください。戦略オブジェクトが複数回使用されると、スレッドセーフの問題が発生する可能性があります。

于 2011-05-30T13:31:20.687 に答える