9

私は基本的に戦略パターンを実装しようとしていますが、「インターフェイス」実装 (同じオブジェクトから継承する) に異なるパラメーターを渡したいのですが、これが可能かどうかはわかりません。間違ったパターンを選択している可能性があります。次のようなエラーが表示されます

「StrategyA」は、継承された抽象メンバー「void DoSomething(BaseObject)」を実装していません

以下のコードで:

abstract class Strategy
{
 public abstract void DoSomething(BaseObject object);
}

class StrategyA : Strategy
{
 public override void DoSomething(ObjectA objectA)
 {
  // . . .
 }
}

class StrategyB : Strategy
{
 public override void DoSomething(ObjectB objectB)
 {
  // . . .
 }
}

abstract class BaseObject
{
}

class ObjectA : BaseObject
{
 // add to BaseObject
}

class ObjectB : BaseObject
{
 // add to BaseObject
}

class Context
{
   private Strategy _strategy;

 // Constructor
 public Context(Strategy strategy)
 {
  this._strategy = strategy;
 }

    // i may lose addtions to BaseObject doing this "downcasting" anyways?
 public void ContextInterface(BaseObject obj) 
 {
  _strategy.DoSomething(obj);
 }

}
4

5 に答える 5

15

戦略パターンを意図したとおりに使用するのではなく、実際に訪問者パターンを再発明しようとしているようです。

また、C# を使用しているので、C# 3.0 で実装されたデザイン パターンの効率性に関する Judith Bishop の論文を読むことをお勧めします。これは、訪問者パターンへの複数のアプローチを詳細にカバーしており、興味深い、関連する有用なアイデアがいくつかあります。

于 2009-12-24T17:33:15.790 に答える
8

C# のメソッド シグネチャには、その名前、型パラメーター リスト、仮パラメーター リストが含まれます。上記のコードでは、「オーバーライド」は仮想メソッドとは異なるシグネチャを持っているため、許可されていません。

戦略パターンの背後にある核となるアイデアは、内部に詳細が隠されている交換可能なアルゴリズムのセットを定義することです。しかし、あなたの戦略が入力として受け入れることができるものが (タイプによって) 異なる場合、それらはもはや交換可能ではありません。したがって、この状況で使用するのは間違ったパターンのようです。

于 2009-12-24T17:44:13.067 に答える
5

次の記事を検討してください: http://hillside.net/plop/2010/papers/sobajic.pdf このパターンは「パラメーター化された戦略パターン」と呼ばれ、必要なものと一致する必要があります。基本的に、戦略パターンに基づいて構築され、戦略 (異なるアルゴリズム) が異なるパラメーターを持つことができます。パラメータは特別なクラス、つまりパラメータ クラスにカプセル化されます。各戦略 (つまり、アルゴリズム) は、特定のアルゴリズムのパラメーター インスタンスのリストを返す GetParameters() メソッドを実装する必要があります。

于 2011-09-20T20:10:45.300 に答える
2

戦略パターンは、同じタイプの入力オブジェクトに対して異なる動作を提供することを目的としています。

あなたが実際にやろうとしていることは文脈依存であり、投稿されたコードからそれを確認できるかどうかはわかりません。

于 2009-12-24T17:40:46.773 に答える
0

次のように Parameters クラスを作成できます。

public class Parameters
{
  public ObjectA {get; set;}
  public ObjectB {get; set;}
}

次のようなパラメーターを受け入れるようにメソッドを変更します。

class StrategyA : Strategy
{
 public override void DoSomething(Parameters parameters)
 {
      //  Now use ObjectA
      if(parameters.ObjectA.SomeProperty == true)
      { ... }
 }
}

このようにして、要件が将来変更された場合にパラメーターを追加できます。別の代替手段は、できるDictionary<string, object>場所を使用することです。

class StrategyA : Strategy
{
     public override void DoSomething(Dictionary<string, object>parameters)
     {
          //  Now use ObjectA
          var someProperty = (bool)parameters["SomeProperty"];
          if() ...
     }
}
于 2010-07-31T01:31:01.403 に答える