6

In pratica sto cercando di implementare un modello di strategia, ma voglio passare diversi parametri all'implementazione delle "interfacce" (che ereditano dallo stesso oggetto) e non so se questo è possibile. Forse sto scegliendo il modello sbagliato, ottengo un errore simile alSchema di strategia con diversi parametri nell'interfaccia (C#)

'StrategyA' non implementa ereditato membro astratto 'DoSomething void (BaseObject)'

con il codice qui sotto:

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 uno scenario così comune, che ho visto implementazioni in cui obj continua a crescere ... –

+0

utilizzare le interfacce, invece di classi esempio interfaccia pubblica { vuoto DoSomething (oggetto BaseObject); } Quindi la strategia eredita quell'interfaccia. Base il tuo SP attorno all'interfaccia o un intefaccia IStrategy che eredita da questa interfaccia.utilizzare BTW DIP per iniezione con un IoC come Ninject – GregJF

risposta

13

Sembra che tu stia effettivamente cercando di reinventare lo Visitor pattern, invece di usare semplicemente il modello di strategia come previsto.

Inoltre, dal momento che stai usando C#, ti consiglio di leggere il documento di Judith Bishop intitolato On the Efficiency of Design Patterns Implemented in C# 3.0. Questo copre più approcci allo schema del visitatore in dettaglio, e ha alcune interessanti idee utili correlate.

+0

sto convertendo 2 diversi formati di file in un formato diverso, se questo aiuta - sto la conversione di formati A e B sia per C – user210757

+0

una sola interfaccia, con un metodo ObjectC ConvertToC(), probabilmente è tutto ciò di cui hai bisogno, in quel caso. Il formato A e il formato B (o una classe che funziona con quei formati) devono solo implementare quell'interfaccia e il gioco è fatto. –

+0

ma se voleva 2 metodi - ObjectC ConvertToC (Objecta a), ObjectC ConvertToC (ObjectB b), credo che avrei ancora lo stesso problema – user210757

2

Lo strategy pattern ha lo scopo di fornire un comportamento diverso sugli oggetti di input dello stesso tipo.

Quello che in realtà stai cercando di fare è dipendente dal contesto, e non sono sicuro che possa essere visto dal codice che è stato pubblicato.

5

Nella firma del metodo C# include il nome, l'elenco dei parametri di tipo e l'elenco dei parametri formale. Nel codice sopra "sostituzioni" hanno diverse firme rispetto al metodo virtuale e quindi non è consentito.

L'idea centrale di Strategy Pattern è la definizione di un insieme di algoritmi intercambiabili con dettagli nascosti all'interno. Ma se le tue strategie differiscono (per tipo) in ciò che possono accettare come input non sono più intercambiabili. Quindi sembra questo uno schema sbagliato da usare in questa situazione.

0

Si potrebbe creare una classe di parametri in questo modo:

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

Il alterare i vostri metodi per accettare parametri quali:

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

questo modo è possibile ulteriori parametri dovrebbe vostre esigenze cambiare in futuro . Un'altra alternativa è quella di utilizzare Dictionary<string, object> dove si può fare:

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

Si potrebbe prendere in considerazione questo articolo: http://hillside.net/plop/2010/papers/sobajic.pdf Il modello si chiama "modello di strategia parametrizzato" e deve corrispondere quello che vi serve. Fondamentalmente, si basa sul modello strategico e consente alle strategie (diversi algoritmi) di avere parametri diversi. I parametri sono incapsulati in classi speciali, ad esempio classi di parametri. Ogni strategia (cioè l'algoritmo) deve implementare il metodo GetParameters() che restituisce l'elenco delle istanze parmaters per algoritmo specifico.

Problemi correlati