tăm de vorbă cu Mark Seemann, co-autorul cărții Dependency Injection Principles, Practices, and Patterns. Mark a fost speaker la ediția de anul trecut a IT Days unde prezentarea sa, Human Code, a câștigat votul publicului. Va fi prezent din nou luna aceasta la Cluj unde va vorbi despre Asynchrnous Injection la conferința The Developers 2019
Vă începeți cartea cu o analogie interesantă între o priză, un sos Béarnaise și Dependency Injection. Care este legătura dintre acestea?
Mark Seemann: Ambele sunt analogii. Există două moduri de a privi Dependency Injection.
Analogia cu priza scoate în evidență ideea de polimorfism și tiparele diverse de design ce rezultă din polimorfism. Priviți priza ca o interfață. Orice ștecher care se potrivește în priză va permite curentului electric să treacă. Prizele diferite (e.g. US vs. Europa) corespund unor interfețe diferite. Adaptorii există, iar tiparul Adapter Design vă permite să faceți ca un obiect să arate ca un altul.
Analogia cu sosul Bèarnaise scoate în evidență ideea că este greu de învățat, dar după ce ai învățat, devine un lucru ușor, de bază chiar. De fapt, sosul Hollandaise ar fi o analogie mai bună, deoarece acesta este sosul de bază de la care obținem sosul Bèarnaise și alte sosuri. Am ales sosul Bèarnaise pentru că este mai cunoscut. Nu mă așteptam ca publicul să știe ce este sosul Hollandaise.
Este Dependency Injection același lucru ca Inversion of Control?
Mark Seemann: Cred că nu este vorba de același lucru și cred că am învățat acest lucru din lucrările lui Martin Fowler. Dependency Injection este o formă de Inversion of Control, dar Inversion of Control este un concept mult mai larg care include și utilizarea de frameworkuri de aplicație.
Totuși, distincția poate fi o luptă pierdută. Pentru mulți programatori, distincția nu există, folosind termenii ca sinonime. Prefer termenul Dependency Injection în toate cazurile în care nu mă refer explicit la un concept mai larg.
Ce tipare de design recomandați să fie utilizate în Dependency Injection? Există și anti-tipare?
Mark Seemann: Cele mai utile tipare sunt Composite, Null Object, Decorator, Chain of Responsibility, Visitor. Dependency Injection este doar un sinonim pentru tiparul Strategy, dar Dependency Injection include tipare pentru modul în care Strategy colaborează cu consumatorii. Cel mai util tipar este Constructor Injection.
Un alt tipar Dependency Injection este Composition Root. Compuneți întregul grafic de obiecte pentru aplicație în punctul de intrare în aplicație.
În ceea ce privește anti-tiparele, cel mai frecvent este Service Locator. Din păcate, programatorii încep de obicei cu acest lucru, iar mulți presupun că acesta este modul recomandat de utilizare a Dependency Injection.
Ambient Context este de evitat.
Utilizarea unui DI Container nu este un anti-tipar, dar mulți cred că Dependency Injection necesită DI Container, iar această gândire duce ușor la anti-tiparul Service Locator. Eu recomand ca, dacă nu știți ce faceți, să nu folosiți DI Container.
La ce trebuie să fie atenți programatorii când verifică o implementare DI?
Mark Seemann: Primul lucru pe care îl verific este dacă Service Locator este prezent. Verific și dacă DI Container este inclus în cod.
Este util să identificăm care este graficul de dependințe din cod. Care părți din cod depind de alte părți? Programatorii își împart codul în librării - deși de multe ori le numesc "straturi" (layers). Aceste librării vor fi conectate unele de altele într-un grafic. Este bine de știut cum arată acest grafic. Poate va trebui să îl desenați pe o hârtie. Cu toate că "analiza dependințelor din grafic" ('dependency graph analysis') poate suna academic și abstract, acest grafic e simplu și se poate realiza în câteva minute.
Am întâlnit multe exemple de cod unde dependințele au fost prost înțelese și implementate. Un grafic de dependințe scoate problemele la lumină.
La ce să ne așteptăm de la prezentarea dumneavoastră de la conferința The Developers 2019?
Să se aștepte să învețe ceva nou.
de Ovidiu Mățan
de Ioana Negruț