SlideShare una empresa de Scribd logo
Dependency Injection con Guice
@jordi9
23 octubre 2010
roadmap
Motivación
Problema
3 aproximaciones y media
Más DI con Guice
Unit Testing
Conclusiones
#bcngtug #guice
motivación
diseño
Diseño típico de una aplicación
problema común
Cómo obtienen los clientes los servicios?
3 aproximaciones y media
The Factory Pattern (Patrón Fábrica)
+ Service Locator
Dependency Injection a mano
Dependency Injection con Guice
parte constante
public interface Dictionary {
void spellchecking(Text text);
}
public class CatalanDictionary
implements Dictionary {
@Override
public void spellchecking(Text text) {
// comprobación en catalán
}
}
Cualquier servicio se mantiene independientemente de la
aproximación
Aproximación #1
The Factory Pattern
factory pattern / client
public class PhoneClient {
Dictionary dictionary;
public void sendSMS(Text text) {
dictionary = DictionaryFactory.getInstance();
dictionary.spellchecking(text);
}
}
factory pattern / service
public static class DictionaryFactory {
static class DictionaryHolder {
static Dictionary instance = new CatalanDictionary();
}
public static Dictionary getInstance() {
return DictionaryHolder.instance;
}
public static void setInstance(Dictionary mock) {
DictionaryHolder.instance = mock;
}
}
factory pattern / consideraciones
Hay que escribir una fábrica para cada objeto y para cada
dependencia - boilerplate code
Hay que escribir una fábrica para cada variación en las
dependencias.
El cliente establece sus dependencias en tiempo de
compilación - Están encapsuladas.
Propagación viral de clases estáticas - static
Difícil reutilizar el código cliente en otro contexto.
Hay que modificar el código para poder hacer unit testing.
Aproximación #1.5
Service Locator
service locator
Tipo especial de fábrica.
Hereda casi todos sus problemas.
Introduce nuevos problemas. eg: no type-safety
Dictionary dictionary = (Dictionary) new ServiceLocator()
.get("CatalanDictionary");
Aproximación #2
Dependency Injection a mano
el principio de hollywood
public class PhoneClient {
private final Dictionary dictionary;
public PhoneClient(Dictionary dictionary) {
this.dictionary = dictionary
}
public void sendSMS(Text text) {
dictionary.spellchecking(text);
}
}
"Don't call us, we'll call you"
DI manual / ventajas
No podemos crear un cliente sin los servicios necesarios.
Dependencias claras.
Podemos reutilizar el cliente con múltiples implementaciones
de un mismo servicio.
Las dependencias pasan de estar en tiempo de compilación a
estar a nivel de de aplicación.
La clase es testeable.
Pero aun tenemos que escribir más codigo fábrica!
Aproximación #3
Dependency Injection con Guice
Google Guice
Framework de DI creado por Google (2007).
Toda aplicación Java lo utilitza: Google Docs, GMail,
Adwords...
objetivos
Evitar escribir fábricas y boilerplate code
Más comprobaciones de tipos - Type safety
Flexibilidad y facilidad para escribir buen código
@Inject
public class PhoneClient {
private final Dictionary dictionary;
@Inject
public PhoneClient(Dictionary dictionary) {
this.dictionary = dictionary
}
public void sendSMS(Text text) {
dictionary.spellchecking(text);
}
}
Aplicamos @Inject para obtener las dependencias.
@Injections
@Inject private Dictionary dictionary;
field injection
method injection
@Inject
public void setDictionary(Dictionary dictionary) {
this.dictionary = dictionary;
}
constructor injection
public class PhoneClient {
private final Dictionary dictionary;
@Inject
public PhoneClient(Dictionary dictionary) {
this.dictionary = dictionary
}
}
modules
public class DictionaryModule extends AbstractModule {
protected void configure() {
bind(Dictionary.class).to(CatalanDictionary.class);
}
}
Tenemos Modules que configuran Guice.   no XML... yay!
public class DictionaryModule implements Module {
public void configure(Binder binder) {
binder.bind(Dictionary.class).to(CatalanDictionary.class);
}
}
versión DRY (Don't Repeat Yourself)
versión JIT (Just In Time)
@ImplementedBy(CatalanDictionary.class)
public class Dictionary {}
bootstrapping
Iniciando una aplicación
public class PhoneRunner {
public static void main(String[] args) {
Injector injector = Guice
.createInjector(new DictionaryModule());
PhoneClient phone = Injector
.getInstance(PhoneClient.class);
phone.sendSMS(new Text("foo text"));
}
}
consideraciones
@Inject es viral.
 
        Solo una clase debería tratar con el Injector.
más Guice i DI…
múltiples implementaciones
public class DictionaryModule extends AbstractModule {
protected void configure() {
bind(Dictionary.class)
.annotatedWith(Catalan.class)
.to(CatalanDictionary.class);
}
}
Binding annotations
public class PhoneClient {
private final Dictionary dictionary;
@Inject
public PhoneClient(@Catalan Dictionary dictionary) {
this.dictionary = dictionary
}
}
Hay que configurarlo en un Module
provider pattern
Servicios que dependen del tiempo de ejecución, de 
librerias de terceros o que se acaban
public interface Provider<T> {
public T get();
}
public class CoffeeJunkie {
CupOfCoffee cupOfcoffee;
@Inject
public CoffeeJunkie(CupOfCoffee cupOfcoffee) {
this.cupOfcoffee = cupOfcoffee;
}
public void drinkTwoCupsOfCoffe() {
cupOfcoffee.drink();
cupOfcoffee.drink(); // <-- is empty!
}
}
provider injection
public class CoffeeModule extends AbstractModule {
protected void configure() {
bind(CupOfCoffee.class).toProvider(new Provider<CupOfCoffee>() {
public CupOfCoffee get() {
return new CupOfCoffe(); // cuidado con el new!
}
});
}
}
public class CoffeeJunkie {
Provider<CupOfCoffee> cupsProvider;
@Inject
public CoffeeJunkie(Provider<CupOfCoffee> cupOfcoffee) {
this.cupsProvider = cupsProvider;
}
public void drinkTwoCupsOfCoffe() {
cupsProvider.get().drink();
cupsProvider.get().drink(); // <-- ok!
}
}
@Provides
since guice 2.0
Métodos que nos dan un objeto en concreto. Tienen que estar en 
un Module
public class CoffeeModule extends AbstractModule {
protected void configure() {
// ...
}
@Provides @WithMilk
public CupOfCoffee provideCupOfCoffeWithMilk() {
return new CupOfCoffe.builder().withMilk().build();
}
}
scopes
Política de reutilización de instancias
    No-scope (por defecto)
    Singleton
    Web: RequestScope, SessionScope...
@Singleton
public class CatalanDictionary ... {
...
}
public class DictionaryModule extends AbstractModule {
protected void configure() {
bind(Dictionary.class)
.to(CatalanDictionary.class)
.in(Scopes.SINGLETON);
}
}
o en un Module
otras características
Aspect Oriented Programming
    con AOP Allicance
bindInterceptor(
Matchers.any(), // classes
Matchers.annotatedWith(Foo.class), // methods
new FooInterceptor() // interceptor
);
Cargar constantes con comprobaciones de tipo.
    gtug.properties -> String gtug; int members;
 
Injections opcionales, estáticas, ...
@Inject(optional=true) Date launchDate;
Integraciones:
    JNDI, Spring, JMX, Struts2, OSGi...
guice 2.0
Multibindings
   Hello Multibinder y MapBinder / útil para plugins
@Inject ImageFinder(Set<UriBuilder> uriBuilders) { ... }
// module
public void configure() {
Multibinder<UriBuilder> uriBinder =
Multibinder.newSetBinder(binder(), UriBuilder.class);
uriBinder.addBinding().to(S3UriBinder.class);
}
AssistedInject
   Hello @Assisted
Private modules
   Soluciona el robot-legs problem: Dos grafos del mismo objeto ligeramente 
   distintos
unit testing
unit testing
Aplicando DI con Guice, nuestro código ya es testeable!
Código (método) que ejecuta un otro código para comprobar su
validez.
funcionamiento
Precondición - Clase a testear - Postcondición (asserts)
características
Rápido, repetible, automático.
frameworks
Junit, TestNG, Mockito, EasyMock, JMock
test con junit
public class StringsTest {
@Test
public void stripAllHTMLForAGivenText() {
String html = "<a>Link</a>";
String expected = "Link";
assertEquals(expected,Strings.stripHTML(html));
}
}
public class Strings {
public static String stripHTML(String input) {
return input.replaceAll("</?+(b)[ˆ<>]++>", "");
}
}
unit test
test con dependencias
// Class under test
CreditCardProcessor creditCardProcessor;
@Test
public void chargeCreditCard() {
creditCardProcessor = Guice.createInjector()
.getInstance(CreditCardProcessor.class);
CreditCard c = new CreditCard("9999 0000 7777", 5, 2009);
creditCardProcessor.charge(c, 30.0);
assertThat(creditCardProcessor.balance(c), is(-30.0));
}
es incorrecto!
@Inject
public CreditCardProcessor(Queue queue) {
this.queue = queue;
}
unit test…?
test con dependencias / mocks
@Test
public void chargeCreditCard() {
Queue queue = mock(Queue.class);
CreditCard c = new CreditCard("9999 0000 7777", 5, 2009);
creditCardProcessor = new CreditCardProcessor(queue);
creditCardProcessor.charge(c, 30.0);
verify(queue).enqueue(c, 30.0);
}
Dependencias falsas: mocks (mockito)
para acabar…
futuro de dependency injection
Google + SpringSource = JSR-330 acabada
Spring 3 - annotation based
Maven 3 - de plexus a guice
guice 3.0
Soporte para JSR-330
guice-persist integrado (antiguo warp-persist)
Más SPI y Extension Points
y más guice!
GIN - GWT INjection, subset de Guice
RoboGuice - Guice en Android. Inject de views, resources...
gracias!
jordi@donky.org
@jordi9

Más contenido relacionado

Similar a Dependency Injection con Guice - GTUG

Msdn Webcast InyeccióN De Dependencias Con Spring Framework
Msdn Webcast   InyeccióN De Dependencias Con Spring FrameworkMsdn Webcast   InyeccióN De Dependencias Con Spring Framework
Msdn Webcast InyeccióN De Dependencias Con Spring Framework
Gabriel Oliva
 
GWT
GWTGWT
Diseño de Patrones (Fachada)
Diseño de Patrones (Fachada)Diseño de Patrones (Fachada)
Diseño de Patrones (Fachada)
Fanny Ruiz
 
Practica9 bases de datos
Practica9 bases de datosPractica9 bases de datos
Practica9 bases de datos
Naty Ortiz Arias
 
Practica9 bases de datos
Practica9 bases de datosPractica9 bases de datos
Practica9 bases de datos
Naty Ortiz Arias
 
Testing & Pizza by Lito & nitsnets
Testing & Pizza by Lito & nitsnetsTesting & Pizza by Lito & nitsnets
Testing & Pizza by Lito & nitsnets
eusonlito
 
Gwt III - Avanzado
Gwt III - AvanzadoGwt III - Avanzado
Gwt III - Avanzado
Manuel Carrasco Moñino
 
1TAP Tema 1-GUI.pptx
1TAP Tema 1-GUI.pptx1TAP Tema 1-GUI.pptx
1TAP Tema 1-GUI.pptx
ATM_SSI
 
Presentación IGALIA
Presentación IGALIAPresentación IGALIA
Presentación IGALIA
alberto_silva
 
Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8
Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8
Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8
Sorey García
 
Saula ana bdii_t7
Saula ana bdii_t7Saula ana bdii_t7
Saula ana bdii_t7
Any Saula
 
Ponencia conic 2009_darc
Ponencia conic 2009_darcPonencia conic 2009_darc
Ponencia conic 2009_darc
Jorge Rodriguez
 
Manual Basico De Struts
Manual Basico De StrutsManual Basico De Struts
Manual Basico De Struts
carlossanchezvillena
 
Aplicación abc. asp net mvc 3
Aplicación abc. asp net mvc 3Aplicación abc. asp net mvc 3
Aplicación abc. asp net mvc 3
jose luis barrientos
 
Abstract Factory
Abstract FactoryAbstract Factory
Abstract Factory
Diego Calderon
 
De zero a 100 con Spring Boot
De zero a 100 con Spring BootDe zero a 100 con Spring Boot
De zero a 100 con Spring Boot
Javier Rodriguez Llorente
 
Test unitarios
Test unitariosTest unitarios
Test unitarios
Donewtech Solutions
 
Guia laboratorios no2-programacion_avanzada
Guia laboratorios no2-programacion_avanzadaGuia laboratorios no2-programacion_avanzada
Guia laboratorios no2-programacion_avanzada
haroldhicc
 
Presentacion #bbmnk
Presentacion #bbmnkPresentacion #bbmnk
Presentacion #bbmnk
Juan Miqueo
 
Taller patrones de diseño
Taller patrones de  diseñoTaller patrones de  diseño
Taller patrones de diseño
tovar1982
 

Similar a Dependency Injection con Guice - GTUG (20)

Msdn Webcast InyeccióN De Dependencias Con Spring Framework
Msdn Webcast   InyeccióN De Dependencias Con Spring FrameworkMsdn Webcast   InyeccióN De Dependencias Con Spring Framework
Msdn Webcast InyeccióN De Dependencias Con Spring Framework
 
GWT
GWTGWT
GWT
 
Diseño de Patrones (Fachada)
Diseño de Patrones (Fachada)Diseño de Patrones (Fachada)
Diseño de Patrones (Fachada)
 
Practica9 bases de datos
Practica9 bases de datosPractica9 bases de datos
Practica9 bases de datos
 
Practica9 bases de datos
Practica9 bases de datosPractica9 bases de datos
Practica9 bases de datos
 
Testing & Pizza by Lito & nitsnets
Testing & Pizza by Lito & nitsnetsTesting & Pizza by Lito & nitsnets
Testing & Pizza by Lito & nitsnets
 
Gwt III - Avanzado
Gwt III - AvanzadoGwt III - Avanzado
Gwt III - Avanzado
 
1TAP Tema 1-GUI.pptx
1TAP Tema 1-GUI.pptx1TAP Tema 1-GUI.pptx
1TAP Tema 1-GUI.pptx
 
Presentación IGALIA
Presentación IGALIAPresentación IGALIA
Presentación IGALIA
 
Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8
Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8
Estrategias para desarrollo crossplatform en Windows Phone 8 y Windows 8
 
Saula ana bdii_t7
Saula ana bdii_t7Saula ana bdii_t7
Saula ana bdii_t7
 
Ponencia conic 2009_darc
Ponencia conic 2009_darcPonencia conic 2009_darc
Ponencia conic 2009_darc
 
Manual Basico De Struts
Manual Basico De StrutsManual Basico De Struts
Manual Basico De Struts
 
Aplicación abc. asp net mvc 3
Aplicación abc. asp net mvc 3Aplicación abc. asp net mvc 3
Aplicación abc. asp net mvc 3
 
Abstract Factory
Abstract FactoryAbstract Factory
Abstract Factory
 
De zero a 100 con Spring Boot
De zero a 100 con Spring BootDe zero a 100 con Spring Boot
De zero a 100 con Spring Boot
 
Test unitarios
Test unitariosTest unitarios
Test unitarios
 
Guia laboratorios no2-programacion_avanzada
Guia laboratorios no2-programacion_avanzadaGuia laboratorios no2-programacion_avanzada
Guia laboratorios no2-programacion_avanzada
 
Presentacion #bbmnk
Presentacion #bbmnkPresentacion #bbmnk
Presentacion #bbmnk
 
Taller patrones de diseño
Taller patrones de  diseñoTaller patrones de  diseño
Taller patrones de diseño
 

Más de Jordi Gerona

Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenches
Jordi Gerona
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
Jordi Gerona
 
Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - Trovit
Jordi Gerona
 
Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)
Jordi Gerona
 
Mercurial
MercurialMercurial
Mercurial
Jordi Gerona
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUG
Jordi Gerona
 

Más de Jordi Gerona (6)

Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenches
 
Google Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & AndroidGoogle Guava - Core libraries for Java & Android
Google Guava - Core libraries for Java & Android
 
Unit Testing - Trovit
Unit Testing - TrovitUnit Testing - Trovit
Unit Testing - Trovit
 
Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)Mitos y otras criaturas startuperas (webbar)
Mitos y otras criaturas startuperas (webbar)
 
Mercurial
MercurialMercurial
Mercurial
 
Unit Testing - GTUG
Unit Testing - GTUGUnit Testing - GTUG
Unit Testing - GTUG
 

Dependency Injection con Guice - GTUG

  • 1. Dependency Injection con Guice @jordi9 23 octubre 2010
  • 2. roadmap Motivación Problema 3 aproximaciones y media Más DI con Guice Unit Testing Conclusiones #bcngtug #guice
  • 4. diseño Diseño típico de una aplicación
  • 5. problema común Cómo obtienen los clientes los servicios?
  • 6. 3 aproximaciones y media The Factory Pattern (Patrón Fábrica) + Service Locator Dependency Injection a mano Dependency Injection con Guice
  • 7. parte constante public interface Dictionary { void spellchecking(Text text); } public class CatalanDictionary implements Dictionary { @Override public void spellchecking(Text text) { // comprobación en catalán } } Cualquier servicio se mantiene independientemente de la aproximación
  • 9. factory pattern / client public class PhoneClient { Dictionary dictionary; public void sendSMS(Text text) { dictionary = DictionaryFactory.getInstance(); dictionary.spellchecking(text); } }
  • 10. factory pattern / service public static class DictionaryFactory { static class DictionaryHolder { static Dictionary instance = new CatalanDictionary(); } public static Dictionary getInstance() { return DictionaryHolder.instance; } public static void setInstance(Dictionary mock) { DictionaryHolder.instance = mock; } }
  • 11. factory pattern / consideraciones Hay que escribir una fábrica para cada objeto y para cada dependencia - boilerplate code Hay que escribir una fábrica para cada variación en las dependencias. El cliente establece sus dependencias en tiempo de compilación - Están encapsuladas. Propagación viral de clases estáticas - static Difícil reutilizar el código cliente en otro contexto. Hay que modificar el código para poder hacer unit testing.
  • 13. service locator Tipo especial de fábrica. Hereda casi todos sus problemas. Introduce nuevos problemas. eg: no type-safety Dictionary dictionary = (Dictionary) new ServiceLocator() .get("CatalanDictionary");
  • 15. el principio de hollywood public class PhoneClient { private final Dictionary dictionary; public PhoneClient(Dictionary dictionary) { this.dictionary = dictionary } public void sendSMS(Text text) { dictionary.spellchecking(text); } } "Don't call us, we'll call you"
  • 16. DI manual / ventajas No podemos crear un cliente sin los servicios necesarios. Dependencias claras. Podemos reutilizar el cliente con múltiples implementaciones de un mismo servicio. Las dependencias pasan de estar en tiempo de compilación a estar a nivel de de aplicación. La clase es testeable. Pero aun tenemos que escribir más codigo fábrica!
  • 18. Google Guice Framework de DI creado por Google (2007). Toda aplicación Java lo utilitza: Google Docs, GMail, Adwords... objetivos Evitar escribir fábricas y boilerplate code Más comprobaciones de tipos - Type safety Flexibilidad y facilidad para escribir buen código
  • 19. @Inject public class PhoneClient { private final Dictionary dictionary; @Inject public PhoneClient(Dictionary dictionary) { this.dictionary = dictionary } public void sendSMS(Text text) { dictionary.spellchecking(text); } } Aplicamos @Inject para obtener las dependencias.
  • 20. @Injections @Inject private Dictionary dictionary; field injection method injection @Inject public void setDictionary(Dictionary dictionary) { this.dictionary = dictionary; } constructor injection public class PhoneClient { private final Dictionary dictionary; @Inject public PhoneClient(Dictionary dictionary) { this.dictionary = dictionary } }
  • 21. modules public class DictionaryModule extends AbstractModule { protected void configure() { bind(Dictionary.class).to(CatalanDictionary.class); } } Tenemos Modules que configuran Guice.   no XML... yay! public class DictionaryModule implements Module { public void configure(Binder binder) { binder.bind(Dictionary.class).to(CatalanDictionary.class); } } versión DRY (Don't Repeat Yourself) versión JIT (Just In Time) @ImplementedBy(CatalanDictionary.class) public class Dictionary {}
  • 22. bootstrapping Iniciando una aplicación public class PhoneRunner { public static void main(String[] args) { Injector injector = Guice .createInjector(new DictionaryModule()); PhoneClient phone = Injector .getInstance(PhoneClient.class); phone.sendSMS(new Text("foo text")); } } consideraciones @Inject es viral.           Solo una clase debería tratar con el Injector.
  • 23. más Guice i DI…
  • 24. múltiples implementaciones public class DictionaryModule extends AbstractModule { protected void configure() { bind(Dictionary.class) .annotatedWith(Catalan.class) .to(CatalanDictionary.class); } } Binding annotations public class PhoneClient { private final Dictionary dictionary; @Inject public PhoneClient(@Catalan Dictionary dictionary) { this.dictionary = dictionary } } Hay que configurarlo en un Module
  • 25. provider pattern Servicios que dependen del tiempo de ejecución, de  librerias de terceros o que se acaban public interface Provider<T> { public T get(); } public class CoffeeJunkie { CupOfCoffee cupOfcoffee; @Inject public CoffeeJunkie(CupOfCoffee cupOfcoffee) { this.cupOfcoffee = cupOfcoffee; } public void drinkTwoCupsOfCoffe() { cupOfcoffee.drink(); cupOfcoffee.drink(); // <-- is empty! } }
  • 26. provider injection public class CoffeeModule extends AbstractModule { protected void configure() { bind(CupOfCoffee.class).toProvider(new Provider<CupOfCoffee>() { public CupOfCoffee get() { return new CupOfCoffe(); // cuidado con el new! } }); } } public class CoffeeJunkie { Provider<CupOfCoffee> cupsProvider; @Inject public CoffeeJunkie(Provider<CupOfCoffee> cupOfcoffee) { this.cupsProvider = cupsProvider; } public void drinkTwoCupsOfCoffe() { cupsProvider.get().drink(); cupsProvider.get().drink(); // <-- ok! } }
  • 27. @Provides since guice 2.0 Métodos que nos dan un objeto en concreto. Tienen que estar en  un Module public class CoffeeModule extends AbstractModule { protected void configure() { // ... } @Provides @WithMilk public CupOfCoffee provideCupOfCoffeWithMilk() { return new CupOfCoffe.builder().withMilk().build(); } }
  • 28. scopes Política de reutilización de instancias     No-scope (por defecto)     Singleton     Web: RequestScope, SessionScope... @Singleton public class CatalanDictionary ... { ... } public class DictionaryModule extends AbstractModule { protected void configure() { bind(Dictionary.class) .to(CatalanDictionary.class) .in(Scopes.SINGLETON); } } o en un Module
  • 29. otras características Aspect Oriented Programming     con AOP Allicance bindInterceptor( Matchers.any(), // classes Matchers.annotatedWith(Foo.class), // methods new FooInterceptor() // interceptor ); Cargar constantes con comprobaciones de tipo.     gtug.properties -> String gtug; int members;   Injections opcionales, estáticas, ... @Inject(optional=true) Date launchDate; Integraciones:     JNDI, Spring, JMX, Struts2, OSGi...
  • 30. guice 2.0 Multibindings    Hello Multibinder y MapBinder / útil para plugins @Inject ImageFinder(Set<UriBuilder> uriBuilders) { ... } // module public void configure() { Multibinder<UriBuilder> uriBinder = Multibinder.newSetBinder(binder(), UriBuilder.class); uriBinder.addBinding().to(S3UriBinder.class); } AssistedInject    Hello @Assisted Private modules    Soluciona el robot-legs problem: Dos grafos del mismo objeto ligeramente     distintos
  • 32. unit testing Aplicando DI con Guice, nuestro código ya es testeable! Código (método) que ejecuta un otro código para comprobar su validez. funcionamiento Precondición - Clase a testear - Postcondición (asserts) características Rápido, repetible, automático. frameworks Junit, TestNG, Mockito, EasyMock, JMock
  • 33. test con junit public class StringsTest { @Test public void stripAllHTMLForAGivenText() { String html = "<a>Link</a>"; String expected = "Link"; assertEquals(expected,Strings.stripHTML(html)); } } public class Strings { public static String stripHTML(String input) { return input.replaceAll("</?+(b)[ˆ<>]++>", ""); } } unit test
  • 34. test con dependencias // Class under test CreditCardProcessor creditCardProcessor; @Test public void chargeCreditCard() { creditCardProcessor = Guice.createInjector() .getInstance(CreditCardProcessor.class); CreditCard c = new CreditCard("9999 0000 7777", 5, 2009); creditCardProcessor.charge(c, 30.0); assertThat(creditCardProcessor.balance(c), is(-30.0)); } es incorrecto! @Inject public CreditCardProcessor(Queue queue) { this.queue = queue; } unit test…?
  • 35. test con dependencias / mocks @Test public void chargeCreditCard() { Queue queue = mock(Queue.class); CreditCard c = new CreditCard("9999 0000 7777", 5, 2009); creditCardProcessor = new CreditCardProcessor(queue); creditCardProcessor.charge(c, 30.0); verify(queue).enqueue(c, 30.0); } Dependencias falsas: mocks (mockito)
  • 36. para acabar… futuro de dependency injection Google + SpringSource = JSR-330 acabada Spring 3 - annotation based Maven 3 - de plexus a guice guice 3.0 Soporte para JSR-330 guice-persist integrado (antiguo warp-persist) Más SPI y Extension Points y más guice! GIN - GWT INjection, subset de Guice RoboGuice - Guice en Android. Inject de views, resources...

Notas del editor

  1. Introduir eventuo, els seus inicis, alguna caracterísitca? escollir tecnologies, descobrir Guice i com va canviar el meu punt de vista
  2. Introduir eventuo, els seus inicis, alguna caracterísitca? escollir tecnologies, descobrir Guice i com va canviar el meu punt de vista
  3. diseny habitual, parlar sobre interficies per separar codi, modularitat, mantenibilitat. parlar de serveis i clients. posar exemple del coche o del telefon.
  4. Destacar el més important, que és delegar la creació dels objectes a la fàbrica.
  5. static = no interface, no polimòrfic, estat global, trenca la modularitat, dificil heredar per la constructora
  6. Parlar del patró, destacar-ho com a tal
  7. comprovació de tipus = generics. exemple llistes.
  8. field / constructor / method injection yup!
  9. field / constructor / method injection yup!
  10. comentari Spring xml - annotations. parlar també del binder, que és l&amp;apos;encarregat de configurar l&amp;apos;injector o guice.
  11. inject viral, comentar errors d&amp;apos;inici
  12. crear annotations és fàcil.
  13. Un Provider es una fabrica que devuelve instancias de un tipo.
  14. posar exemple d&amp;apos;hibernate i les sessions
  15. Un Provider es una fabrica que devuelve instancias de un tipo.
  16. parlar d&amp;apos;un test com pensar el que volem o esperem que passi.
  17. parlar d&amp;apos;un test com pensar el que volem o esperem que passi.
  18. parlar d&amp;apos;un test com pensar el que volem o esperem que passi.