6

Básicamente estoy tratando de implementar un patrón de estrategia, pero quiero pasar diferentes parámetros a la implementación de "interfaces" (que heredan del mismo objeto) y no sé si Esto es posible. Tal vez estoy eligiendo un patrón equivocado, me sale un error similar alPatrón de estrategia con diferentes parámetros en la interfaz (C#)

'StrategyA' no implementa miembro abstracta heredada 'HacerAlgo vacío (BaseObject)'

con el código de abajo:

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 tal escenario común, que he visto implementaciones donde obj sigue creciendo y creciendo ... –

+0

utilizan interfaces en lugar de clases por ejemplo interfaz pública { vacío HacerAlgo (BaseObject objeto); } Luego, Strategy heredará esa interfaz. Base su SP alrededor de la interfaz o una interfaz de IStrategy que hereda de esta interfaz.Por cierto uso DIP para Inyección con un IoC como Ninject – GregJF

Respuesta

13

Parece que en realidad está tratando de reinventar el Visitor pattern, en lugar de simplemente usar el patrón de Estrategia de la manera en que fue diseñado.

Además, como estás usando C#, te recomendaría leer el artículo de Judith Bishop titulado On the Efficiency of Design Patterns Implemented in C# 3.0. Esto abarca múltiples enfoques del patrón de visitante en detalle, y tiene algunas ideas útiles interesantes relacionadas.

+0

Estoy convirtiendo 2 formatos de archivo diferentes a un formato diferente, si eso ayuda - Estoy convirtiendo los formatos A y B ambos en C – user210757

+0

Una interfaz, con un método ObjectC ConvertToC() es probablemente todo lo que necesitas, en ese caso. El formato A y el Formato B (o una clase que funciona con esos formatos) solo necesitan implementar esa interfaz, y listo. –

+0

pero si lo desea 2 métodos - ObjectC ConvertToC (ObjectA a), ObjectC ConvertToC (ObjectB b), creo que todavía tendría el mismo problema – user210757

2

El strategy pattern está destinado a proporcionar un comportamiento diferente en los objetos de entrada del mismo tipo.

Lo que en realidad estás tratando de hacer depende del contexto, y no estoy seguro de que se pueda ver en el código que se publicó.

5

En la firma de método C# incluye su nombre, tipo de lista de parámetros y lista de parámetros formales. En el código anterior "anulaciones" tienen firmas diferentes que el método virtual y, por lo tanto, no está permitido.

La idea central detrás de Strategy Pattern es definir un conjunto de algoritmos intercambiables con detalles ocultos en el interior. Pero si sus estrategias difieren (por tipo) en lo que pueden aceptar como entrada, ya no son intercambiables. Entonces parece que este es un patrón incorrecto para usar en esta situación.

0

Se puede crear una clase de parámetros, así:

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

La alterar sus métodos para aceptar parámetros tales como:

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

De esta manera puede parámetros adicionales debe sus requerimientos cambiar en el futuro . Otra alternativa es utilizar Dictionary<string, object> donde se puede hacer:

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

Es posible que desee considerar este artículo: http://hillside.net/plop/2010/papers/sobajic.pdf El patrón se llama "patrón de estrategia parametrizado" y debe coincidir con lo que necesita. Básicamente, se basa en el patrón de estrategia y permite estrategias (diferentes algoritmos) para tener diferentes parámetros. Los parámetros están encapsulados en clases especiales, es decir, clases de parámetros. Cada estrategia (es decir, algoritmo) necesita implementar el método GetParameters() que devuelve la lista de instancias de parmaters para un algoritmo específico.

Cuestiones relacionadas