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 GUICE

 Setter injection  Lightweight DI framework  Dipendenze dichiarate come metodi setter  Class injection (@Inject – JSR‐330) public class MovieLister {  Configurazione 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, Object> public class MovieLister {  // L’annotazione istruisce il container di risolvere Non è possibile avere due oggetti dello stesso tipo // automaticamente le dipendenze dichiarate  È possibile utilizzare qualificatori ulteriori per questo caso @Inject public setFinder(MovieFinder finder) {  Si integra con AOP, Servlet spec., DAO, ... this.finder = finder; } // ...  @Named, @Singleton, @SessionScoperd, @RequestScoped... } public static void main(String[] args) {  Field injection // Guice.createInjector() takes your Modules, and returns a new // Injector instance. Most applications will call this method public class MovieLister { // exactly once, in their main() method. // Risolta automaticamente dall’injector. Piu’ conciso ma Injector injector = Guice.createInjector(new MovieModule()); // meno verificabile @Inject MovieFinder finder; // Now that we've got the injector, we can build objects. } MovieLister lister = injector.getInstance(MovieLister.class); }

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 ApplicationContext ctx =  Utilizza semplici POJO: Bean new ClassPathXmlApplicationContext(  Supporta sia constructor, che setter injection "com/springinaction/springidol/filename.xml");

 // ... 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">

@Bean return new ColonMovieFinder("movies.csv"); } } ApplicationContext ctx = [...] new AnnotationConfigApplicationContext(MovieConfig .class); Ingegneria del software mod. A Riccardo Cardin 17 Ingegneria del software mod. A Riccardo Cardin 18

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 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