DEPENDENCY INJECTION INGEGNERIA DEL SOFTWARE Università degli Studi di Padova Dipartimento di Matematica Corso di Laurea in Informatica, A.A. 2014 – 2015 Architetturali [email protected] Dependency injection, Model view controller
Ingegneria del software mod. A Riccardo Cardin 2
INTRODUZIONE E CONTESTO PROBLEMA
MovieLister nasconde le Scopo Esempio naive proprie dipendenze in un metodo. Separazione del comportamento di una componente dalla risoluzione delle sue dipendenze
Motivazione Collegare due componenti in modo esplicito ne aumenta l’accoppiamento Progettazione unit‐test difficoltosa Riutilizzo scarso della componente Scarsa manutenibilità Le dipendenze vanno minimizzate!!!
Ingegneria del software mod. A Riccardo Cardin 3 Ingegneria del software mod. A Riccardo Cardin 4 PROBLEMA STRUTTURA
Utilizzo di classi factory Inversion of Control Utilizza metodi statici nel recupero di istanze concrete Il ciclo di vita degli oggetti è gestito da una entità ad interfacce esterna (container) Si può fare di meglio... Tutti i framework moderni implementano IoC Dependency Injection con IoC Le dipendenze sono “iniettate” dal container La componente dichiara solo le sue dipendenze Minimizzazione del livello di accoppiamento Diversi tipi di injection Constructor injection Setter injection
Ingegneria del software mod. A Riccardo Cardin 5 Ingegneria del software mod. A Riccardo Cardin 6
STRUTTURA SOLUZIONE
Dependency Injection con IoC Constructor injection Assembler risolve le dipendenze delle componenti Dipendenze dichiarate come parametri del costruttore Il ciclo di vita degli oggetti è deciso dal container public class MovieLister { private MovieFinder finder; Configurazione: meta‐linguaggio (XML) o programmatica public MovieLister(MovieFinder finder) { // Dichiarazioe dip. this.finder = finder; Cambio di movie finder Cambio di configurazione } // ... }
Vantaggi Permette di costruire oggetti validi sin dalla loro istanziazione Favorisce la costruzione di oggetti immutabili Svantaggi Telescoping A volte è difficile comprendere il significato dei parametri
Ingegneria del software mod. A Riccardo Cardin 7 Ingegneria del software mod. A Riccardo Cardin 8 SOLUZIONE GOOGLE GUICE
Setter injection Lightweight DI framework Dipendenze dichiarate come metodi setter Class injection (@Inject – JSR‐330) public class MovieLister { Configurazione Java estendendo AbstractModule private MovieFinder finder; public void setFinder(MovieFinder finder) { public class MovieModule extends AbstractModule { this.finder = finder; @Override } // ... protected void configure() { } // Istruisce il container di come risolvere la dipendenza
bind(MovieFinder.class).to(ColonMovieFinder.class); } Vantaggi }
Individuazione precisa delle dipendenze e dei loro nomi public class MovieLister { Lavora meglio con le gerarchie di classi // L’annotazione istruisce il container di risolvere // automaticamente le dipendenze dichiarate Svantaggi @Inject public MovieLister(MovieFinder finder) { La componente è costruita per passi this.finder = finder; } // ... Non è abilitante all’immutabilità }
Ingegneria del software mod. A Riccardo Cardin 9 Ingegneria del software mod. A Riccardo Cardin 10
GOOGLE GUICE GOOGLE GUICE
Lightweight DI framework Lightweight DI framework Method (setter) injection Cointainer è una struttura Map
Ingegneria del software mod. A Riccardo Cardin 11 Ingegneria del software mod. A Riccardo Cardin 12 SPRING SPRING
“Spring is a «lightweight» inversion of control and aspect oriented Configurazione XML container framework” org.springframework.beans.factory.BeanFactory Lightweight Implementazione del pattern factory, costruisce e risolve le Non è intrusivo, gli oggetti sviluppati non dipendono da dipendenze classi del framework Framework/Container org.springframework.context.ApplicationContext La configurazione utilizza XML, o annotazioni, o Java Costruita sulla bean factory, fornisce ulteriori funzionalità Lo sviluppatore può concentrarsi sulla logica di business AOP, transazionalità, ... Cointainer è una struttura Map
// ... JEE replacement MVC, Front controller, DI, AOP, JDBC Template, Security ... MovieLister ml = (MovieLister) ctx.getBean("movieLister");
Ingegneria del software mod. A Riccardo Cardin 13 Ingegneria del software mod. A Riccardo Cardin 14
SPRING SPRING
Configurazione XML Configurazione XML Dependency injection attraverso proprietà Dependency injection attraverso costruttori Spring risolve automaticamente la scelta del costruttore Utilizzo metodi setter e getter "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
SPRING JAVASCRIPT
Wiring utilizzando annotazioni Dependency injection in Javascript @Inject/@Autowired Container è una mappa [string, function] Ricerca per tipo il bean della proprietà e lo usa come id Linguaggio non tipizzato staticamente Si utilizza su costruttori, proprietà, ... Non ha interfacce esplicite Il bean non deve essere ambiguo
Disambiguazione tramite @Named per l’ID @Inject JS è strutturato a moduli (module pattern) private Instrument instrument; Injection di oggetti o interi moduli
@Inject @Named("guitar") // Fornisce nome differente dal tipo Esistono diverse librerie (API) per la DI private Instrument instrument2; RequireJS/AMD ‐ http://requirejs.org/ Autodiscovery Inject.js ‐ http://www.injectjs.com/ @Component, @Controller, @Service, ... AngularJS (framework) ‐ https://angularjs.org/ Ingegneria del software mod. A Riccardo Cardin 19 Ingegneria del software mod. A Riccardo Cardin 20 ANGULARJS ANGULARJS
Javascript framework Dependency Injection Client‐side $provide: risolve le dipendenze fra le componenti Model‐View‐Whatever Viene invocato direttamente da Angular al bootstrap // Provide the wiring information in a module Ritorna il servizio MVC per alcuni aspetti (controller)… angular.module('myModule', []). $provide …MVVM per altri (two‐way data binding) // Teach the injector how to build a 'greeter' // Notice that greeter itself is dependent on '$window' factory('greeter', function($window) { // This is a factory function, and is responsible for Utilizza HTML come linguaggio di templating // creating the 'greet' service. Non richiede operazioni di DOM refresh return { greet: function(text) { Controlla attivamente le azioni utente, eventi del browser $window.alert(text); "Ricetta" di come } }; costruire greeter Dependence injection });
Fornisce ottimi strumenti di test // Request any dependency from the $injector angular.injector(['myModule', 'ng']).get('greeter');
Ingegneria del software mod. A Riccardo Cardin 21 Ingegneria del software mod. A Riccardo Cardin 22
ANGULARJS ANGULARJS
Dependency Injection Dependency Injection Factory methods: costruiscono le componenti Utilizzano recipe (ricette) angular.module('myModule', []). config(['depProvider', function(depProvider){ //... }]). factory('serviceId', ['depService', function(depService) { //... }]). directive('directiveName', ['depService', function(depService) { //... }]). filter('filterName', ['depService', function(depService) { //... }]). run(['depService', function(depService) { //... }]);
Ingegneria del software mod. A Riccardo Cardin 23 Ingegneria del software mod. A Riccardo Cardin 24 CONCLUSIONI RIFERIMENTI
Dependency injection means giving an object its own Design Patterns, Elements of Reusable Object Oriented Software, GoF, 1995, Addison‐Wesley instance variables. Really. That’s it. James Shore Inversion of Control Containers and the Dependency Injection pattern http://martinfowler.com/articles/injection.html Vantaggi Google Guice – Motivation https://github.com/google/guice/wiki/Motivation Migliora la fase di testing Spring vs Guice: The one critical difference that matters Isolamento delle componenti Maggior riuso http://gekkio.fi/blog/2011‐11‐29‐spring‐vs‐guice‐the‐one‐critical‐ Migliora la resilienza del codice difference‐that‐matters.html Spring – The IoC Container Manutenzione e correzioni componenti specifiche http://docs.spring.io/spring/docs/current/spring‐framework‐ Migliora la flessibilità reference/html/beans.html La disponibilità di più componenti simili permette di scegliere Angular Dependency Injection https://docs.angularjs.org/guide/di a runtime la migliore JavaScript Dependency Injection http://merrickchristensen.com/articles/javascript‐dependency‐ injection.html Ingegneria del software mod. A Riccardo Cardin 25 Ingegneria del software mod. A Riccardo Cardin 26