Creazione di un oggetto pronto per essere utilizzato e rimuovere le proprietà - con IoC

1

Ho una domanda riguardante le specifiche della creazione dell'oggetto e l'uso delle proprietà. Una buona pratica consiste nel mettere tutte le proprietà in uno stato tale che l'oggetto sia utile quando è stato creato. I costruttori di oggetti aiutano a garantire che vengano create le dipendenze richieste.

Mi sono ritrovato a seguire un modello ultimamente e poi a mettere in dubbio la sua adeguatezza.
Il modello appare così ...

 public class ThingProcesser
  {
    public List<Thing> CalculatedThings { get; set; }

    public ThingProcesser()
    {
        CalculatedThings = new List<Thing>();
    }

    public double FindCertainThing()
    {
        CheckForException();
        foreach (var thing in CalculatedThings)
        {
            //do some stuff with things...
        }
    }

    public double FindOtherThing()
    {
        CheckForException();
        foreach (var thing in CalculatedThings)
        {
            //do some stuff with things...
        }
    }

    private void CheckForException()
    {
        if (CalculatedThings.Count < 2) throw new InvalidOperationException("Calculated things must have more than 2 items");
    }
  }

L'elenco degli elementi non è stato modificato, ma è stato controllato dai metodi. Esistono diversi metodi sulla classe e per evitare di dover passare l'elenco di cose a ciascuna funzione come parametro del metodo, l'ho impostato una volta sulla classe. Mentre funziona, viola il principio del minimo stupore?

Da quando ho iniziato a utilizzare IoC, mi ritrovo a non attaccare le cose nel costruttore, per evitare di dover usare un modello di fabbrica. Ad esempio, posso discutere con me stesso e dire che il ThingProcessor ha davvero bisogno di un elenco per funzionare, quindi l'oggetto dovrebbe essere costruito in questo modo.

 public class ThingProcesser
    {
        public List<Thing> CalculatedThings { get; set; }

        public ThingProcesser(List<Thing> calculatedThings)
        {
            CalculatedThings = calculatedThings;
        }
    }

Tuttavia, se lo facessi, complicherebbe le cose per IoC, e questo scenario sembra appena appropriato per qualcosa come il modello di fabbrica.

Quindi, in sintesi, ci sono delle buone linee guida per quando qualcosa dovrebbe essere parte dello stato dell'oggetto, o passato come parametro del metodo? Quando si utilizza IoC, il modello di fabbrica è il modo migliore per gestire gli oggetti che devono essere creati con stato? Se qualcosa deve essere passato a più metodi in una classe, lo rende un buon candidato come parte dello stato degli oggetti?

    
posta GetFuzzy 01.06.2014 - 22:10
fonte

1 risposta

0

While this works, does it violate the principle of least astonishment?

Suppongo. Ancora più importante, unisce strettamente un sacco di cose a questi metodi che non tutti (individualmente) necessitano e presenta un contratto troppo ampio con il mondo esterno.

Since starting to use IoC I find myself not sticking things into the constructor, to avoid having to use a factory pattern.

Che cosa? Non riesco a vedere come queste cose siano in qualche modo correlate. Se qualcosa ha bisogno di IFoo , allora prendi un IFoo . Se si desidera utilizzare anche contenitori IoC per fornire un'implementazione concreta di IFoo , andare avanti. Il tuo costruttore non ha bisogno di saperlo.

So in summary, are there some good guidelines for when something should be part of the object state, vs. passed as a method parameter?

Chi possiede lo stato? Se è una parte intrinseca della tua classe, utilizzata in più funzioni della classe, allora la tua classe possiede lo stato. Altrimenti, passalo.

If something has to be passed to multiple methods in a class, does that render it a good candidate to be part of the objects state?

Forse, ma non è un candidato per includere qualcosa nella tua classe, è un odore di codice. Significa che questa altra strana classe ha bisogno che questi dati funzionino, ma i dati non ne fanno parte.

È un po 'impercettibile, ma "oh, lo affronterò nel costruttore" è un buon modo per violare il Principio di Responsabilità Unica e fare una classe schifosa. "Hmmmm, non funziona, e se invece facessi XYZ?" è un buon modo per rifattorizzare più classi in modo che abbiano una bella responsabilità singola e interagiscano in modo pulito e disaccoppiato.

    
risposta data 01.06.2014 - 23:12
fonte

Leggi altre domande sui tag