web-dev-qa-db-ja.com

変更された戦略設計パターン

私は最近デザインパターンを調べ始めましたが、コード化している1つのことは、1つの小さな違いを除いて、戦略パターンに完全に適合します。

基本的に、私のアルゴリズムの一部(すべてではない)には、追加のパラメーターが1つまたは2つ渡される必要があります。

だから私はどちらかが必要になります

  • 彼らの計算メソッドを呼び出すときにそれらに追加のパラメーターを渡します

または

  • それらをConcreteAlgorithmクラス内の変数として格納し、アルゴリズムを呼び出す前に更新できるようにします。

このニーズのための設計パターンはありますか/戦略パターンに固執しながらこれをどのように実装できますか?

クライアントオブジェクトをすべてのアルゴリズムに渡し、そこに変数を格納し、特定のアルゴリズムで必要な場合にのみそれを使用することを検討しました。しかし、これはどちらも扱いにくく、戦略パターンのポイントを打ち負かすと思います。

明確にするために、私はJavaで実装しているので、オプションのパラメーターを贅沢に使用しないでください(これでうまく解決します)。

11
Megan Walker

サミュエル、各戦略が取る1つの共通クラスにパラメーターをカプセル化し、その共通パラメータークラスを拡張して、一部の戦略が特に必要とする動作を追加することは可能ですか?

例えば。

_StrategyParameter //Base strategy parameter that most of the strategies need
        ^
        |
        |
SpecialStrategyParameter // will be used for strategies that need more parameter
_

次に、次のような戦略階層を定義します。

_Interface MyStrategy {
   void myStrategyMethod(StrategyParameter parameter);
}

class MyNormalStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}
_

上記の戦略を次のように呼び出します:myNormalStrategyInstance.myStrategyMethod(strategyParameter);

_class MySpecializedStrategy extends MyStrategy {
   void myStrategyMethod(StrategyParameter parameter) {
       //implement the logic here
   }
}
_

代わりにSpecialStrategyParameterインスタンスを渡して上記の戦略を呼び出します:mySpecializedStrategy.myStrategyMethod(specialStrategyParameter);

不明な点がある場合は更新してください。説明/明確化させていただきます。

5
peakit

戦略を明確にする必要があります。

すべては、どのようにseアルゴリズムに依存するかによって異なります。クライアントクラスが異なる戦略の実装を交換可能に使用するには、すべてに共通のabstractionが必要です。それらが同じインターフェースに従っていない場合、おそらく必要なものは異なりますabstractions

私は以前にconfigurable戦略を使用しましたが、構築時に具象クラスをパラメーター化します。

interface Strategy {
  int calculate();
}

class ConcreteStrategyThatNeedsAParameter implements Strategy {
  private final int param;
  public ConcreteStrategyThatNeedsAParameter(int param) {
    this.param = param;
  }
  public int calculate() { 
    // uses param...
  }
}

someoneでも、このクラスのインスタンスを作成してクライアントに渡す必要があります。ただし、クライアントはStrategyインターフェースについてのみ知る必要があります。

これは、戦略methodがパラメーターを取る場合にも機能しますが、クライアントknowsにこれらのパラメーターを渡し、それらをall実装に渡します。

4
Jordão

署名がインターフェースで明確に定義されている限り、それはまだ戦略パターンに準拠しています。

記述されているパターンは、予想される動作を示す、最も単純な形式であるため、元の意図を維持している限り、パターンを装飾できます。もちろん、それはあなたがパターンに従っていきたいと思っていることです。パターンが合わない場合、またはパターンが存在するという理由だけでパターンを使用しても意味がありませんが、あなたの場合は問題ないと思います。

1
Ian

デザインパターンブックを見ると、渡されたパラメーターの使用量が少ないかまったくないSimpleStrategyが存在すること、またはパラメーターが1つのサイズに適合する/最も一般的ではない乗数であること自体は間違いありません。ここでの設計上の選択は、使用されない結果となる余分な処理に関して、これがあなたを傷つけるかどうかです。

0
pjv

peakitが提供する上記の回答を拡張して、抽象化を使用できます。ここでpeakitのコードを使用しています-

インターフェースMyStrategy {abstract void myStrategyMethod(StrategyParameter parameter); }

クラスMyNormalStrategy extends MyStrategy {public override void myStrategyMethod(StrategyParameter parameter){//ここにロジックを実装する}}

クラスMySpecializedStrategy extends MyStrategy {public override void myStrategyMethod(StrategyParameter parameter、ExtraStrategyParameter extraParameter){//ここにロジックを実装する}}

私があなたの質問を正しく理解している場合、特定のアルゴリズムに追加のパラメーターを渡したいと思っていますか?これがあなたが探していたものかどうか教えてください。

0
user20020