Iniezione delle dipendenze: a che punto posso creare un nuovo oggetto?


13

Sto eseguendo il refactoring di un'applicazione PHP e sto provando a fare l' iniezione di dipendenza (DI) il più possibile.

Sento di avere una buona conoscenza di come funziona e posso certamente vedere le mie lezioni diventare molto più snelle e più robuste.

Sto eseguendo il refactoring in modo da poter iniettare una dipendenza piuttosto che creare un nuovo oggetto all'interno della classe, ma a un certo punto dovrò creare alcuni oggetti, ovvero utilizzare la newparola chiave temuta .

Il problema che ho riscontrato ora è a che punto posso effettivamente creare nuovi oggetti? Sembra che finirò in una classe di alto livello, creando un sacco di nuovi oggetti in quanto non c'è altro posto dove andare. Questo sembra sbagliato.

Ho letto alcuni blog che usano le classi factory per creare tutti gli oggetti, e quindi si inietta la factory in altre classi. È quindi possibile chiamare i metodi factory e factory crea il nuovo oggetto per te.

La mia preoccupazione nel farlo è che ora le mie lezioni di fabbrica saranno newgratuite! Immagino che potrebbe essere OK dato che sono classi di fabbrica, ma ci sono alcune regole a cui attenersi quando si usano un modello di fabbrica e DI, o sto andando fuori strada?



Raccomando IoC per servizi e politiche. Per le classi di modello o di aiuto che userei semplicemente new. Naturalmente ci sono alcuni punti di ingresso in cui è necessario chiamare nel contenitore IoC, ma non dovrebbero essercene molti. In genere si configura l'IoC una volta, quindi si richiede la risoluzione di una classe per richiesta. Nel caso di MVC, in genere è il controller.
Codici InChaos

La classe di livello superiore che menzioni fa parte della Root di composizione. È tutt'altro che sbagliato.
Facio Ratio

Risposte:


12

Dopo un po 'di ricerche su Google per questo, sembra che (come menzionato in un commento sopra) la classe di livello superiore di cui stavo parlando si chiama Root Composizione .

Sembra davvero essere la soluzione accettata per aggiungere la creazione di tutti gli oggetti all'interno di questo Root di composizione (o facendo riferimento a un contenitore IoC da qui).

La mia preoccupazione originale era che questa classe di alto livello sarebbe diventata un po 'un casino. Questo è vero in una certa misura, ma i pro valutano i contro. Ad esempio, posso vedere che la leggibilità, la testabilità e la manutenibilità di tutte le altre mie classi sono migliorate.

La classe di livello superiore può essere un po 'disordinata, piena di newe set_property()ma devo dire che in realtà preferisco avere tutto questo codice in un posto, piuttosto che sparpagliato in tutte le altre classi

Un'altra pagina utile che discute i risultati delle prestazioni di questo metodo qui


1
+1 perché non ho mai sentito parlare di "Root composizione" prima d'ora.
c_maker,

2

Una classe di fabbrica sarà newspruzzata dappertutto. Sarebbe creare qualunque oggetto tu stia richiedendo e probabilmente le dipendenze di quell'oggetto. Poiché il lavoro nelle fabbriche è quello di creare un'istanza dell'oggetto corretto per te newin questa classe non è una brutta cosa.

DI è così che hai un design liberamente accoppiato. È possibile apportare modifiche all'applicazione modificando la dipendenza fornita a ciascun oggetto. Rendi la tua applicazione flessibile, estensibile e facile da testare.

Al livello superiore, avrai un codice che crea un'istanza di un paio di fabbriche, imposta connessioni ai servizi e invia una risposta. Avrà un numero newsufficiente di chiamate statiche per istanziare oggetti necessari per l'applicazione. Quello sarebbe dove appartiene.


-2

I miei due centesimi qui:

Sto refactoring di un'applicazione php e sto provando a fare l'iniezione di dipendenza il più possibile

Non dichiari se stai usando un framework di iniezione di dipendenza. Penso che dovresti assolutamente. Usa qualcosa che ti offre le funzionalità di cui hai bisogno: /programming/9348376/guice-like-dependency-injection-frameworks-in-php .

Il problema che ho riscontrato ora è a che punto posso effettivamente creare nuovi oggetti? Sembra che finirò in una classe di alto livello, creando un sacco di nuovi oggetti in quanto non c'è altro posto dove andare. Questo sembra sbagliato.

Normalmente si utilizza la configurazione o un punto centrale per l'istanza degli oggetti iniziali che compongono l'applicazione. Il contenitore creerà gli oggetti per te.

Quindi accedi agli oggetti (servizi, provider, controller ...) tramite il contenitore IoC. Creerà in modo trasparente un oggetto per te, se necessario, o ti darà un riferimento all'istanza esistente appropriata.

Ovviamente, all'interno della tua particolare implementazione di oggetti puoi istanziare altri oggetti su cui non hai bisogno di DI (strutture dati, tipi personalizzati, ecc.), Ma questa è una normale programmazione.

Ho letto alcuni blog che usano le classi factory per creare tutti gli oggetti, e quindi si inietta la factory in altre classi. È quindi possibile chiamare i metodi factory e factory crea il nuovo oggetto per te.

Normalmente, usi una Factory se vuoi che il framework IoC crei un'istanza di alcuni oggetti IoC attraverso le tue fabbriche (questo è necessario quando si crea un'istanza di un oggetto particolare richiede del lavoro extra). Se puoi semplicemente creare i tuoi oggetti con "new Object ()" e impostare alcune proprietà, non devi necessariamente usare un modello Factory.

In altre parole, direi che l'utilizzo di un modello Factory per una classe o un gruppo di classi dipende dal modo in cui si desidera modellare quelle classi, non dal fatto che si utilizzi DI (a meno che l'implementazione DI non richieda esplicitamente fabbriche, il che è insolito).

Configura anche il tuo framework IoC per usare una Factory quando stai usando una libreria di terze parti che richiede già l'uso di una Factory. In questo caso non hai alcun controllo su questo e devi dire al tuo contenitore IoC: "hey, quando chiedo una di queste interfacce, devi usare questa fabbrica per fornirmi un'istanza appropriata".

La mia preoccupazione nel farlo è che ora le mie lezioni di fabbrica saranno un nuovo gioco per tutti! Immagino che questo potrebbe andare bene in quanto sono classi di fabbrica, ma ci sono alcune regole a cui attenersi quando si usano il modello di fabbrica e DI, o sto andando lontano dal segno qui.

In questo caso, sembra che non sia necessario utilizzare i pattern Factory per questi oggetti / servizi / controller / qualunque cosa, e puoi semplicemente configurare il tuo IoC per creare un'istanza con "nuovo" la classe appropriata e iniettare tutto il resto.

Spero possa essere d'aiuto.


grazie per la risposta, ma sicuramente il contenitore IoC è la "classe di alto livello" a cui mi riferivo. Se riesco solo a creare oggetti lì dentro, sarà un casino giusto.
Gaz_Edge,

4
doing DI manually beats the whole purpose of using an Inversion of Control container- Se con questo intendi "... che sta centralizzando le tue dipendenze in un file di configurazione" allora hai ragione, perché è tutto ciò che un contenitore IoC fa davvero. Il vero obiettivo di DI è il disaccoppiamento e puoi farlo fornendo le tue dipendenze in un metodo di costruzione. Non è necessario un framework DI per farlo.
Robert Harvey,

mmm non crei oggetti, chiedi loro il contenitore IoC (da qualsiasi luogo tu sia necessario) o usi l'iniezione di campi / argomenti in modo che alle tue classi vengano automaticamente iniettate le classi appropriate, create sempre dal contenitore IoC.
Jjmontes,

1
Concordo sul fatto che è necessario un framework per applicazioni molto grandi . Molte applicazioni non sono così grandi e non beneficiano della complessità aggiuntiva dell'utilizzo di un framework DI.
Robert Harvey,

2
Non ho detto che lo fosse. Ho semplicemente detto che non è necessario un contenitore DI per farlo.
Robert Harvey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.