Diciamo che abbiamo 1001 clienti che costruiscono direttamente le loro dipendenze piuttosto che accettare iniezioni. Refactoring del 1001 non è un'opzione secondo il nostro capo. In realtà non è nemmeno consentito l'accesso alla loro fonte, solo i file di classe.
Quello che dovremmo fare è "modernizzare" il sistema che questi 1001 clienti attraversano. Possiamo refactoring che tutto ciò che ci piace. Le dipendenze fanno parte di quel sistema. E alcune di quelle dipendenze dovremmo cambiare per avere una nuova implementazione.
Quello che vorremmo fare è avere la possibilità di configurare diverse implementazioni di dipendenze per soddisfare questa moltitudine di client. Purtroppo, DI non sembra un'opzione in quanto i clienti non accettano iniezioni con costruttori o setter.
Le opzioni:
1) Rifattora l'implementazione del servizio che i client usano in modo che faccia ciò di cui i clienti hanno bisogno ora. Bang, abbiamo finito Non flessibile. Non complesso.
2) Rifattora l'implementazione in modo che deleghi il suo lavoro a un'altra dipendenza che acquisisce attraverso una fabbrica. Ora possiamo controllare quale implementazione usano tutti rifattando la fabbrica.
3) Rifattora l'implementazione in modo che deleghi il suo lavoro a un'altra dipendenza che acquisisce tramite un localizzatore di servizi. Ora possiamo controllare quale implementazione usano tutti configurando il localizzatore di servizio che potrebbe essere semplicemente un hashmap
di stringhe sugli oggetti con un piccolo casting in corso.
4) Qualcosa a cui non ho ancora pensato.
L'obiettivo:
Riduci al minimo il danno al design causato dal trascinamento del vecchio codice client mal progettato in futuro senza aggiungere complessità inutile.
I clienti non dovrebbero conoscere o controllare l'implementazione delle loro dipendenze ma insistono nel costruirli con new
. Non possiamo controllare new
ma controlliamo la classe che stanno costruendo.
La mia domanda:
Che cosa ho omesso di considerare?
do you really need a possibility to configure between different implementations? For what purpose?
Agilità. Molte incognite La direzione vuole il potenziale per il cambiamento. Solo perdere la dipendenza dal mondo esterno. Anche test.
do you need need a run time mechanics, or just a compile time mechanics to switch between different implementations? Why?
È abbastanza probabile compilare la meccanica del tempo. Tranne test.
which granularity do you need to switch between implementations? All at once? Per module (each containing a group of classes)? Per class?
Del 1001 solo uno viene eseguito attraverso il sistema in qualsiasi momento. Cambiare ciò che tutti i client usano contemporaneamente è probabile che vada bene. Il controllo individuale delle dipendenze è probabilmente importante però.
who needs to control the switch? Only your/your developer team? An administrator? Each client on his own? Or the maintenance developers for the client's code? So how easy/robust/foolproof does the mechanics need to be?
Dev per test. Amministratore come cambiano le dipendenze dell'hardware esterno. Deve essere facile da testare e configurare.
Il nostro obiettivo è mostrare che il sistema può essere rifatto rapidamente e modernizzato.
actual use case for the implementation switch?
Uno è, alcuni dati saranno forniti dal software fino a quando la soluzione hardware non sarà pronta.