2016-04-15 42 views
5

ho i seguenti dati di simulazione:Implementazione di una fabbrica per la composite

interface ISimulationData 
{ 
    string Name { get; } 
    int[] Heights { get; } 
    int[] Temperatures { get; } 
} 

E la seguente interfaccia per la generazione:

interface ISimulation 
{ 
    void Generate(); 
} 

Utilizzando la Composite modello per rappresentare singolo o multi simulazioni:

interface ISimpleSimulation : ISimulation 
{ 
    int Height { get; } 
    int Temperature { get; } 
} 

interface IMultiSimulation : ISimulation 
{ 
    IEnumerable<ISimulation> GetSimulations(); 
} 

E io ho t ha seguito fabbrica interfaccia:

interface ISimulationFactory 
{ 
    ISimulation CreateSimulation(ISimulationData simulationData); 
} 

implementazioni concrete per i tipi di simulazione:

class SimpleSimulation : ISimpleSimulation 
{ 
    public int Height { get; set; } 
    public int Temperature { get; set; } 

    public SimpleSimulation(int height, int temperature) 
    { 
     Height = height; 
     Temperature = temperature; 
    } 

    public void Generate() 
    { 
     //Height/temperature parameters used here. 
    } 
} 

abstract class MultiSimulation : IMultiSimulation 
{ 
    public void Generate() 
    { 
     foreach (ISimulation subSimulation in GetSimulations()) 
     { 
      subSimulation.Generate(); 
     } 
    } 

    public abstract IEnumerable<ISimulation> GetSimulations(); 
} 

Se viene specificato più di un'altezza, poi una simulazione viene generato per ogni altezza:

class MultiHeightsSimulation : MultiSimulation 
{ 
    private readonly int[] _heights; 

    public MultiHeightsSimulation(int[] heights) 
    { 
     _heights = heights; 
    } 

    public override IEnumerable<ISimulation> GetSimulations() 
    { 
     ISimulationFactory factory = new SimulationFactory(); 

     foreach (int height in _heights) 
     { 
      //yield return factory.CreateSimulation(???); 
     } 
    } 
} 

Analogamente, se viene specificata più di una temperatura, viene generata una simulazione per ciascuna temperatura:

class MultiTemperaturesSimulation : MultiSimulation 
{ 
    private readonly int[] _temperatures; 

    public MultiTemperaturesSimulation(int[] temperatures) 
    { 
     _temperatures = temperatures; 
    } 

    public override IEnumerable<ISimulation> GetSimulations() 
    { 
     ISimulationFactory factory = new SimulationFactory(); 

     foreach (int temperature in _temperatures) 
     { 
      //yield return factory.CreateSimulation(???) 
     } 
    } 
}  

concreta attuazione per la fabbrica:

class SimulationFactory : ISimulationFactory 
{ 
    public ISimulation CreateSimulation(ISimulationData simulationData) 
    { 
     if (simulationData.Heights.Length > 1) 
     { 
      return new MultiHeightsSimulation(simulationData.Heights); 
     } 

     if (simulationData.Temperatures.Length > 1) 
     { 
      return new MultiTemperaturesSimulation(simulationData.Temperatures); 
     } 

     return new SimpleSimulation(simulationData.Heights[0], simulationData.Temperatures[0]); 
    } 
} 

Ora io sono confuso su come procedere con il seguente: scenario multi-altezza e multi-temperatura

  • spedizione combinate ?

ho mostrato solo l'altezza e la temperatura, ma ci sono molti altri parametri che si comportano allo stesso modo, quindi sono davvero alla ricerca di una soluzione adeguata che gestisce gli scenari multi-X, con accoppiamento minimo.

  • ISimulationFactory ha esposto solo un metodo, che prende ISimulationData.

Ora, si può vedere che MultiHeightsSimulation e MultiTemperaturesSimulation chiedono la fabbrica di creare simulazioni (semplice) ad una determinata altezza/temperatura. Attualmente, non ci sono metodi forniti dalla fabbrica e mi chiedevo se avrebbe senso esporre quei metodi in fabbrica? Non confonderebbe i client di ISimulationFactory che non dovrebbero essere a conoscenza dei dettagli di implementazione della fabbrica?

In attesa di sentire il vostro feedback. Grazie!

+1

La situazione che descrivi profuma come un caso di uso di 'Decorator' per me. Ci penserò meglio e tornerò da te. –

+0

Mi sento come se ci fosse un sacco di over-engineering in corso qui ... Pensi che tutta la complessità sia necessaria? –

+0

anche i clienti desiderano creare SimpleSimulations? in caso negativo, è possibile rendere interni gli overload di fabbrica SimpleSimulation? –

risposta

0

vostra fabbrica di simulazione accetta già un parametro ISimulationData che ha array per le due variabili che si sta attualmente interessati con:

opzione
int[] Heights { get; } 
int[] Temperatures { get; } 

Uno sarebbe quello di avere SimulationFactory generare una simulazione per ogni combinazione degli elementi in questi array (tipo di prodotto cartesiano). Quindi, se avessi solo una altezza e 5 temperature, avresti implicitamente il tuo MultiTemperaturesSimulation.Tuttavia potresti anche passare in 5 altezze e 4 temperature, nel qual caso la fabbrica genererebbe 20 simulazioni (una per ogni combinazione di altezza e temperatura) ...

Questo sarebbe abbastanza facile da adattare per gestire più dimensioni, come li aggiungi, più tardi. Quindi potresti avere 3 umiditá, 4 altezze e 5 temperature, che risulterebbero in 3 x 4 x 5 = 60 simulazioni.

Probabilmente si desidera aggiungere del codice per assicurarsi che vi sia almeno un elemento in ciascuno degli array nel parametro ISimulationData in fabbrica in questo caso (poiché se uno degli array ha zero elementi, si finisce con zero simulazioni - che probabilmente non ha senso e dovrebbe portare a un ArgumentException).