2010-01-13 13 views
9

Quando si ha a che fare con oggetti che richiedono dati noti solo al runtime, come un nome utente e una password, dove dovrebbe accadere l'istanziazione dell'oggetto: utilizzando nuovo, in fabbrica o in un contenitore DI?Contenitore DI, fabbrica o nuovo per oggetti effimeri?

Per esempio, ho potuto solo new un oggetto una volta che ho i dati:

UserCredentials creds = 
    new UserCredentials(dialog.getUsername(), dialog.getPassword()); 

Oppure, potrei usare una fabbrica:

UserCredentials creds = 
    CredentialsFactory.create(dialog.getUsername(), dialog.getPassword()); 

Oppure, potrei utilizzare un provider all'interno di un Contenitore DI (che in questo caso sarebbe essenzialmente un factory parametrico). [Esempio di codice omesso.]

Sembra sia sbagliato usare il contenitore DI per qualcosa di così semplice, ma sembra anche sbagliato non usarlo al massimo.

risposta

7

Come sempre, dipende, ma come regola generale, una fabbrica statica come la seconda opzione è solo raramente una buona idea.

new un oggetto UserCredential sembra una scelta equa perché la classe UserCredentials si presenta come una classe concreta e autonoma che può essere completamente istanziata con tutti i suoi invarianti dal nome utente e dalla password.

In altri casi, il tipo che si desidera creare potrebbe rappresentare un'astrazione di per sé. In questo caso, non è possibile utilizzare la parola chiave new, ma è necessario utilizzare una Fabbrica astratta .

L'utilizzo di una fabbrica astratta è spesso molto utile perché consente di comporre un'istanza da una combinazione di valori di runtime e altre dipendenze. Vedere here per ulteriori informazioni.

L'utilizzo di un Abstract Factory aiuta anche con unità di test perché semplicemente è possibile verificare che il valore di ritorno o stato finale o qualsiasi altra cosa che ti interessa è legato all'uscita del Abstract Factory - per il quale si può facilmente fornire un Prova Double perché è ... astratto.

+0

non avevo nemmeno consapevolmente pensato di fabbrica statica rispetto fabbrica astratta. Grazie per il commento sul valore aggiunto in merito. –

0

Per me, utilizzo DI per creare un accoppiamento più libero tra gli oggetti. Se le dipendenze degli oggetti sono molto influenzate dalla creazione di un oggetto usando new, allora non vedo perché non si possa usare DI o inoltrare la creazione dell'oggetto a una factory. Questo ti dà più controllo e mantiene le tue lezioni accoppiate.

Dipende davvero da quando e dove avrai bisogno di questo oggetto e se ci saranno delle dipendenze non necessarie come risultato.

0

Se si dispone già di un contenitore DI per l'applicazione, utilizzare questo approccio. In caso contrario, utilizzare un metodo di fabbrica.

2

Il blog di test di google ha a post which tries to answer this question. L'idea di base è che puoi classificare ciascuna delle tue classi come "nuova" o "iniettabile", e che è giusto semplicemente "rinnovare" le novità.

distinguo 2 categorie principali di "newables":

valori
  • come int, string, DateTime, eccetera.
  • entità come Customer, Order, Employee, ecc. Penso che la tua classe UserCredentials rientri in questa rubrica.

È importante rendersi conto che le novità possono avere un comportamento (verificabile). Se si commette l'errore di pensare che newables non dovrebbero avere alcun test di comportamento o di unità, ci si ritroverà con il anemic domain model anti-modello.

Un effetto collaterale di avere "novità" con il comportamento è che questo comportamento non può essere estratto in modo analogo nei test unitari dei prodotti iniettabili. Questo va bene; è normale avere un forte accoppiamento tra il tuo modello di dominio e il resto della tua applicazione.

Inoltre, ai newables è consentito conoscere gli iniettabili, ma cooperano solo con loro in modo transitorio. Ad esempio, UserCredentials non deve prendere un IUserDatabase come argomento del costruttore. Invece, potrebbe esserci un metodo UserCredentials.Verify(IUserDatabase).

modifica: Attualmente non sono più così sicuro di ciò che ho scritto sopra. Le entità possono anche essere costruite tramite fabbriche (iniettabili) invece di chiamare direttamente il loro costruttore. L'implementazione di fabbrica può quindi iniettare cose nell'entità.

+0

Il tuo link "modello dominio anemico" fa riferimento all'articolo "Nuovo o Nuovo". –

+0

grazie, ora è riparato. –

+0

+1 in particolare per l'avviso sul modello anemico – NoxArt

Problemi correlati