Domanda

Questo è principalmente un esperimento mentale. Quindi, tutto questo è il codice di esempio. Il mio obiettivo era quello di utilizzare il modello specifiche per eliminare i blocchi giganti di codice condizionale all'interno di una fabbrica. Quindi, con questo campione Ho un oggetto StatusData che voglio ottenere un'implementazione di IStatusUpdate che è appropriato per per esso.

Ho la seguente serie di test:

    [TestMethod]
    public void Factory_Interface_Should_Return_IStatusUpdate()
    {
      var factory = MockRepository.GenerateMock<IUpdateFactory<StatusData>>();
      var obj = MockRepository.GenerateStub<IStatusUpdate>();

      var data = new StatusData();
      factory.Stub(x => x.Get(data)).Return(obj);

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(IStatusUpdate));
    }

    [TestMethod]
    public void StatusUpdateFactory_Should_Return_IStatusUpdate()
    {
      var factory = new StatusUpdateFactory();
      var data = new StatusData();

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(IStatusUpdate));   
    }

    [TestMethod]
    public void StatusUpdateFactory_Should_Return_NewStatusUpdate_When_Status_Is_New()
    {
      var data = new StatusData(Status.New);
      var factory = new StatusUpdateFactory();

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(NewStatusUpdate));
    }

La mia implementazione di fabbrica sembra così lontano in questo modo:

public class StatusUpdateFactory:IUpdateFactory<StatusData>
  {
    public IStatusUpdate Get(StatusData item)
    {
      IList<ISpecification<StatusData>> specs = GetSpecifications();

      foreach (var spec in specs)
      {
        if (spec.IsSatisfiedBy(item))
          //how do I do this?
           return new NewStatusUpdate();

      }
      return null;
    }

    private IList<ISpecification<StatusData>> GetSpecifications()
    {
      var returnList = new List<ISpecification<StatusData>>();
      var specTypes = this.GetType().Assembly.GetTypes()
                        .Where(z => z.IsInstanceOfType(typeof(ISpecification<StatusData>)))
                        .ToList();


      specTypes.ForEach(x => returnList.Add(Activator.CreateInstance(x) as ISpecification<StatusData>));

      return returnList;

    }
  }

Dove sto cadendo verso il basso è ancora una volta ho scoperto una specifica che è soddisfatto dalle oggetto di stato, come posso mappare tale specifica a un tipo che implementa IStatusUpdate .. Stumped.

Qualcuno ha giustamente suggerito che ho bisogno di una mappatura delle specifiche per gli esecutori IStatusUpdate. Questa mappatura sembra essere una responsabilità della fabbrica, appeso fuori della specifica puzza come una violazione della SRP. Potrei creare una classe Mapper che ha quella responsabilità, ma che non sembra molto generico e solleva anche la questione come faccio a mappare il mapper alle specifiche.

C'è ancora un po 'salto qui mi manca.

È stato utile?

Soluzione

Così sto assumendo stiamo davvero concentrandosi su questo insieme di linee:

if (spec.IsSatisfiedBy(item))
          return new NewStatusUpdate();

e presumo che stai chiedendo come in questa forma attuale questo può essere fatto. Sembra voce dovrebbe sostenere come

interface ISpecSupport<T>
{
    bool ItemSpecsContain(ISpecification<T> spec);
}

Poi il metodo spec.IsSatisfiedBy può prendere in questo tipo di interfaccia ed eseguire il metodo.

In altre parole credo di essere dicendo che l'oggetto dovrebbe portare una sorta di descrizione di quello che è (in termini di specifiche). Sto indovinando che è un elenco di qualche tipo, ma non ne sono sicuro. Sono sicuro che probabilmente avete pensato a questo, quindi se è possibile aggiungere qualsiasi cosa che sarebbe utile.

Inoltre, invece di quanto sopra forse si potrebbe riorganizzare in questo modo:

if (item.Satisfies(spec))
    return new NewStatusUpdate();

Allora questo modo non è necessario utilizzare il modello molto visitatore diffamato (penso che è quello che stavo descrivendo prima di questo). E 'più diretto in quanto la voce sembra che sarebbe possedere le specifiche e in questo modo si sta permettendo la voce di decidere se soddisfa le specifiche.

Se non si desidera che questa logica tenuto all'interno dell'oggetto (che vorrei capire) e si utilizza un elenco di proprietà di qualche tipo (o stai fresco con la riflessione) si potrebbe scavare nei dettagli dell'oggetto con un validatore spec indipendente. In realtà, un validatore indipendente potrebbe non essere una cattiva idea per cominciare. Io non sono così sicuro che la capacità di sapere se una specifica corrisponde a un oggetto è una responsabilità che dovrebbe rimanere con una specifica individuale.

Altri suggerimenti

Se ho capito bene, si vuole, dato un oggetto che implementa ISpecification si desidera un oggetto che implementa IStatusUpdate?

Nel vostro nessuno campione di questi tipi sono definiti, in modo da non so se c'è qualche relazione tra di loro si potrebbe utilizzare.

Ma è probabile che vi sia bisogno bisogno di qualche fabbrica per contenere il codice, o di un metodo ISpecification.GetUpdate () per fare la creazione dell'oggetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top