Uso l'iniezione delle dipendenze con Guice e la maggior parte delle volte sono piuttosto soddisfatto . Ma a volte, è difficile ottenere le dipendenze dove sono necessarie e, a volte, è impossibile.
Un esempio estremo è che MyResponse.toString()
restituisce alcuni JSON, dove MyResponse
contiene un elenco di DTO o un'eccezione. Ci sono dei requisiti, che lo stacktrace dovrebbe essere mostrato ai tester, il che significa che alcune informazioni sull'utente connesso devono essere fornite in qualche modo. Inoltre, quando eseguo il test localmente, ovviamente voglio sempre vedere lo stacktrace, anche quando disconnesso. E ci sono più tali regole.
Ovviamente, questa dipendenza può essere inclusa in MyResponse
o fornita come argomenti (anche se non per il metodo toString()
, ma sono d'accordo che toString()
dovrebbe essere usato di solito solo per il debug). Questo diventa piuttosto brutto quando viene aggiunta una nuova dipendenza di questo tipo. Ad esempio, ho appena dovuto aggiungere un messaggio di utente finale localizzato alla rappresentazione JSON dell'eccezione. Il numero di tali dipendenze di seconda classe è cresciuto lentamente rispetto al numero di dipendenze rilevanti per la funzionalità di base.
A volte possono essere ben aggregati, ad esempio, posso fornire un Gson
correttamente configurato, che si occupa del nascondimento dello stacktrace condizionale e della generazione di messaggi localizzati dell'utente finale. (*) Ma spesso non lo fa funzionano bene e finisco per passare un sacco di argomenti, o passare inutilmente grandi aggregati di dipendenza, o creare aggregati monouso. Alla fine, mi sembra di abusare di DI, poiché inizia a rendere il codice più brutto piuttosto che più bello.
Mi chiedo, se c'è un punto in cui dovrei semplicemente rinunciare e dire "questi dettagli noiosi saranno disponibili da un thread locale (o anche un singleton)"? Non credo ostacolerebbe il test in quanto queste dipendenze difficilmente hanno importanza e quando lo fanno, possono essere impostate secondo necessità.
(*) Questo può sembrare di attribuire troppe responsabilità alla povera istanza Gson
, tuttavia, è la cosa responsabile della conversione di oggetti in JSON, quindi dovrebbe farlo esattamente come necessario. Il Gson
è composto da un gruppo di adattatori e rende il ThrowableAdapter
consapevole del nascondiglio dello stacktrace e la generazione di messaggi utente localizzati sembra una buona idea. L'unico problema è che le informazioni necessarie (1. Dovrebbe essere mostrato lo stacktrace? 2. Qual è la lingua per il messaggio?) Deve essere passato in qualche modo ad esso.
Pensandoci meglio, potrei avvolgere Throwable
in MyThrowableWithUserInfo
e scrivere un adattatore per questo (posso sempre fare questo wrapping prima di aver bisogno di Gson). In questo caso particolare, sembra essere la soluzione DI perfetta.
In generale, non è così bello come potrebbe esserci qualcosa da buttare da qualche parte nel profondo dell'oggetto da serializzare e aggiungere queste informazioni a loro potrebbe essere impossibile. Ho paura, sarebbe necessaria una modifica locale del thread, ma questo hack può essere limitato solo al processo di serializzazione, il che lo rende molto meno brutto.