Is it better to expose or hide dependency in OOP?
È meglio fare entrambe le cose.
Prima di spiegarmi, permettimi di esplorare i problemi con le tue proposte.
Let's say I have an object A, which is too big(having too many methods and variables).
So, I break it down to smaller objects.
Questo è buono. Rompa sempre gli oggetti fino a quando non hanno una sola responsabilità, cioè, una sola ragione per cui potrebbero mai cambiare. Ciò non significa che possano avere un solo metodo o dipendenza, ma dovrebbero concentrarsi su un'idea.
- create an Object C in Class B, and create an Object B in Class A. Then, create Object A in main method.
A seconda di qualcosa non è come sapere come crearlo. Questa idea richiede che A (e B) facciano entrambe le cose. Non abbiamo rotto A perché lo stava facendo molto in primo luogo?
Creerò eccezioni per oggetti valore (Stringhe e simili) ma in generale mi piace separare l'uso dalla costruzione.
- create Object A, B, and C through dependency injection in main method.
Questo suona bene, A usa B ma non lo costruisce. B usa C ma non lo costruisce. Per quanto riguarda le applicazioni così grandi che hanno bisogno di più di 26 lettere dell'alfabeto per dare loro nomi univoci? Main può diventare improvvisamente un posto occupato.
Ci sono una serie di framework per le dipendenze che ti piacerebbero risolvere questo problema per te se vendi la tua anima a loro. Cioè, diventa dipendente da loro.
Se sei un po 'testardo puoi usare schemi creativi. I GoF funzionano ancora. Puoi anche usare i modelli creazionali più recenti, il builder Josh funziona bene in Java e in altre lingue con problemi con i nomi. Ci sono altri costruttori che ti consente di avere incredibili livelli di controllo sulla creazione se sei disposto a inserire lo sforzo .
Questo arriva fino alle lingue specifiche del dominio interno (iDSL). Questi ti permettono di definire essenzialmente il tuo linguaggio all'interno di Java (o quasi tutti gli altri) e il compilatore di Java lo compilerà per te. Questo ti dà il controllo completo della creazione e dell'iniezione di oggetti. Ma può richiedere un lavoro considerevole. Calpesta leggermente qui perché questa tana di coniglio è profonda.
Questo mi porta alla mia raccomandazione "fai entrambe le cose".
Un'abitudine di successo che ho sviluppato è accettare tutto come un'iniezione nei miei oggetti comportamentali, ma costruirli con iniettori specializzati che conoscono buoni valori predefiniti che richiedono poche o nessuna iniezioni. Puoi avere, diciamo, 5 iniettori della stessa classe che lo costruiscono in 5 modi diversi. Puoi avere un iniettore che costruisce 5 oggetti comportamentali tutti ben cablati insieme. È anche possibile iniettare iniettori negli iniettori e farli intrecciare un grafo di oggetto comportamentale.
Identifica i buoni valori predefiniti se esistono e usa quelli per creare il tuo iniettore di base. Alcuni tendono a usare metodi statici come iniettori, ma possono essere essi stessi oggetti in piena regola. In realtà è più potente.
Ecco come "fai entrambi". Le dipendenze sono esposte per oggetti comportamentali. Gli oggetti creazionali nascondono le dipendenze, eseguendo il lavoro che altrimenti sarebbe diffuso su tutto il main.
Ciò che risolve è una tensione fondamentale tra le buone API della macchina e l'usabilità umana. Ciò che rende una classe iniettabile flessibile non costituisce un buon costruttore di classe utilizzabile umano. Quando mi ritrovo a voler rendere più semplice la costruzione di un oggetto, raggiungo un altro oggetto per farlo funzionare. Non distraggo l'oggetto del comportamento con i suoi dettagli di creazione.
Ho usato diversi framework di dipendenze per le iniezioni e sono arrivato alla conclusione che tutto quello che hanno davvero finito per me stava esprimendo la creazione di oggetti in un'altra lingua (sia xml che @annotations). Risulta che puoi fare tutto in java. Scegli i nomi migliori in modo che le persone sappiano in che tipo di classe si trovano ed è altrettanto mantenibile.
Fatto in questo modo, un look in main mostrerà il collegamento di alcuni grafici di oggetti in scatola e una chiamata a un metodo su uno di questi oggetti per iniziare il tutto ticchettando. Questo è l'unico posto in cui mixo la creazione e l'utilizzo. Devi farlo da qualche parte.
Come tutto ciò può essere esagerato, ma con il giusto equilibrio rende la codifica un po 'più semplice.