Dependency Injection - da bomb!


El ejemplo en UML es el siguiente:



La implementación del Provider, simplemente es una pequeña factoría de clase que Guice invocará cuando necesite una instancia de ese tipo.
- Ejemplo de inyección @Inject:
import java.util.*;
public class House {
private ArrayList<Window> windows = new ArrayList<Window>();
private ArrayList<Door> doors = new ArrayList<Door>();
public House addWindow(Window window) {
this.windows.add(window);
return this;
}
public House addDoor(Door door) {
this.doors.add(door);
return this;
}
public String Description() {
String text;
text = "This is a house with " + windows.size() + " Windows and \n";
text = text + doors.size() + " Doors, the Windows are: \n";
Iterator<Window> winIterator = windows.iterator();
while (winIterator.hasNext()) {
text = text + (" " + winIterator.next().size() + " \n");
}
text = text + "and the Doors are \n";
Iterator<Door> doorIterator = doors.iterator();
while (doorIterator.hasNext()) {
text = text + (" " + doorIterator.next().size() + " \n");
}
return text;
}
}
Window.java
public class Window {
private int width;
private int height;
public Window(int width, int height) {
setWidth(width);
setHeigth(height);
}
public String size() {
return "Size " + height + "x" + width;
}
public void setWidth(int width) {
this.width = width;
}
public int getWidth() {
return width;
}
public void setHeigth(int height) {
this.height = height;
}
public int getHeigth() {
return height;
}
}
Door.java
public class Door {
private int width;
private int height;
public Door(int width, int height) {
setWidth(width);
setHeigth(height);
}
public String size() {
return "Size " + height + "x" + width;
}
public void setWidth(int width) {
this.width = width;
}
public int getWidth() {
return width;
}
public void setHeigth(int height) {
this.height = height;
}
public int getHeigth() {
return height;
}
}
HouseProvider.java, WindowProvider.java and DoorProvider.java
import com.google.inject.Provider;
public class HouseProvider implements Provider<House> {
public House get() {
return new House();
}
}
import com.google.inject.Provider;
public class WindowProvider implements Provider<Window> {
public Window get() {
return new Window(10, 10);
}
}
import com.google.inject.Provider;
public class DoorProvider implements Provider<Door> {
public Door get() {
return new Door(30, 10);
}
}
BuilderModule.java
import com.google.inject.AbstractModule;
public class BuilderModule extends AbstractModule {
protected void configure() {
bind(Window.class).toProvider(WindowProvider.class);
bind(Door.class).toProvider(DoorProvider.class);
bind(House.class).toProvider(HouseProvider.class);
}
}
BuilderConstructor.java
import com.google.inject.Inject;
import com.google.inject.Provider;
public class BuilderConstructor {
@Inject
private Provider<House> houseProvider;
@Inject
private Provider<Door> doorProvider;
@Inject
private Provider<Window> windowProvider;
public House getHouse() {
return houseProvider.get();
}
public Door getDoor() {
return doorProvider.get();
}
public Window getWindow() {
return windowProvider.get();
}
}
BuilderTest.java
import com.google.inject.Guice;
import com.google.inject.Injector;
public class BuilderTest {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BuilderModule());
BuilderConstructor m = injector.getInstance(BuilderConstructor.class);
House house = m.getHouse();
house.addDoor(m.getDoor()).addWindow(m.getWindow())
.addWindow(m.getWindow());
System.out.println(house.Description());
}
}
El resultado de ejecutar esta aplicación es el siguiente:
This is a house with 2 Windows and
1 Doors, the Windows are:
Size 10x10
Size 10x10
and the Doors are
Size 10x30
Por lo tanto, aquí tenemos nuestra aplicación con inyección. En el BuilderConstructor, se añaden los @Inject en las variables de tipo Provider, y estas se crear automáticamente cuando se hace la inyección.
De todas maneras, esto es solo la punta del iceberg, hay muchas más opciones para aprender dentro del tema del DI. Dependency Injection minimiza la complejidad a través de la abstracción, y permite que tengamos una aplicación más modular y nos permite hacer el testing de una manera más fácil.
- Enlaces de interés:
http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/
http://martinfowler.com/articles/injection.html
Comments
Post a Comment