6

Ich versuche grundsätzlich, ein Strategie-Muster zu implementieren, aber ich möchte verschiedene Parameter an die "Schnittstellen" Implementierung übergeben (die von dem gleichen Objekt erben) und nicht wissen, ob Das ist möglich. Vielleicht bekomme ich bin das falsche Muster wählen, ich einen Fehler wieStrategie Muster mit verschiedenen Parametern in der Schnittstelle (C#)

‚StrategyA‘ implementiert nicht geerbt abstraktes Mitglied ‚Leer DoSomething (Baseobject)‘

mit dem folgenden Code:

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); 
} 

} 
+0

+1 so ein gängiges Szenario, ich habe Implementierungen gesehen, wo obj wächst und wächst ... –

+0

Verwenden Schnittstellen statt Klassen zB öffentliche Schnittstelle { Leere DoSomething (Baseobject-Objekt); } Dann haben Strategie diese Schnittstelle erben. Basieren Sie Ihren SP auf der Schnittstelle oder einer IStrategy-Schnittstelle, die von dieser Schnittstelle erbt.BTW verwenden DIP für die Injektion mit einem IoC wie Ninject – GregJF

Antwort

13

Es klingt, als ob Sie tatsächlich versuchen, das Visitor pattern neu zu erfinden, anstatt das Strategie-Muster so zu verwenden, wie es beabsichtigt war.

Auch, da Sie C# verwenden, würde ich empfehlen, Judith Bishop Papier mit dem Titel On the Efficiency of Design Patterns Implemented in C# 3.0 zu lesen. Dies umfasst mehrere Ansätze für das Besuchermuster im Detail und enthält einige interessante, damit verbundene nützliche Ideen.

+0

ich konvertiere 2 verschiedene Dateiformate in ein anderes Format, wenn das hilft - ich konvertiere Format A und B beide zu C – user210757

+0

Eine Schnittstelle, mit einer ObjectC ConvertToC() Methode, ist wahrscheinlich alles was du brauchst, in diesem Fall. Format A und Format B (oder eine Klasse, die mit diesen Formaten arbeitet) müssen nur diese Schnittstelle implementieren, und Sie sind fertig. –

+0

aber wenn gewünscht 2 Methoden - ObjectC ConvertToC (ObjectA a), ObjectC ConvertToC (ObjectB b), ich denke, ich hätte immer noch das gleiche Problem – user210757

2

Die strategy pattern soll ein unterschiedliches Verhalten bei Eingabeobjekten des gleichen Typs bieten.

Was Sie eigentlich versuchen, ist kontextabhängig, und ich bin nicht sicher, ob es aus dem Code, der gepostet wurde, zu sehen ist.

5

In der C# -Methodensignatur sind Name, Typ Parameterliste und Formalparameterliste enthalten. Im obigen Code haben "overrides" unterschiedliche Signaturen als die virtuelle Methode und ist daher nicht erlaubt.

Der Kerngedanke von Strategy Pattern besteht darin, eine Reihe austauschbarer Algorithmen mit Details zu definieren, die im Inneren versteckt sind. Wenn sich Ihre Strategien jedoch (nach Typ) in dem unterscheiden, was sie als Eingabe akzeptieren können, sind sie nicht mehr austauschbar. Es scheint also ein falsches Muster in dieser Situation zu sein.

0

Sie könnten eine Parameter-Klasse wie so erstellen:

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

Die Ihre Methoden ändern Parameter zu akzeptieren, wie zum Beispiel:

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

Auf diese Weise können zusätzliche Parameter sollten in Zukunft Ihre Anforderungen ändern . Eine weitere Alternative ist Dictionary<string, object> zu verwenden, wo Sie tun können:

class StrategyA : Strategy 
{ 
    public override void DoSomething(Dictionary<string, object>parameters) 
    { 
      // Now use ObjectA 
      var someProperty = (bool)parameters["SomeProperty"]; 
      if() ... 
    } 
} 
4

Sie können diesen Artikel betrachten wollen: http://hillside.net/plop/2010/papers/sobajic.pdf Das Muster wird „parametrisierte Strategie Muster“ genannt und sollte dem entsprechen, was Sie brauchen. Grundsätzlich baut es auf dem Strategie-Pattern auf und erlaubt Strategien (unterschiedliche Algorithmen) verschiedene Parameter zu haben. Parameter sind in speziellen Klassen, d. H. Parameterklassen, eingekapselt. Jede Strategie (d. H. Ein Algorithmus) muss die GetParameters() -Methode implementieren, die die Liste der Parmater-Instanzen für einen bestimmten Algorithmus zurücksendet.

Verwandte Themen