web 2.0

lunes, 12 de abril de 2010

Inyección de la Dependencia I: Práctico y Fácil

Spring es un Framework de código abierto, creado originalmente para mitigar la odiosa complejidad de los EJB (La especificación de EJB 3 ha sido considerablemente más ligera y fácil de utilizar). Una de las características más conocidas de Spring es trabajar con la Inyección de la Dependencia y la Programación Orientada a Aspectos. Omitiremos un poco la discusión sobre el término Inversión del Control (IoC) que es más general, para otra ocasión!


Alta Cohesión y Débil Acoplamiento

Se dice que el Software debe tener dos características fundamentales, una alta cohesión y un débil acoplamiento. La cohesión se refiere a la manera en la que agrupamos todos los "artefactos de software" (un término quizá más apropiado es "unidad de software"). Con "agrupar" debe entenderse a la facilidad con la que pueden ensamblarse todos nuestros componentes de software, métodos, clases, paquetes, etc.

El débil acoplamiento se refiere al grado de dependencia que existe entre las unidades de software, es decir, si tenemos dos clases, A y B, y alguna de ellas depende en gran medida de la otra y no esta presente, la clase o método dependiente no podrá realizar efectivamente su tarea. El acoplamiento a nivel de métodos es más fácil de comprender con el siguiente ejemplo:


public int multiplicar(int a, int b){
        int c = resta(a,b);
        return 2 * c;
    }
    
    public int resta(int a, int b){
        return a-b;
    }

Vemos pues que existe una fuerte dependencia del método multiplicar con el método restar! El método multiplicar llama al método restar. En gran medida, esto es lo que debemos evitar! Sin embargo, es importante aclarar el término "débil acoplamiento" y "desacoplamiento", este segundo término da a entender algo total y absoluto, mientras que el primero dice que puede haber acoplamiento por que definitivamente no es posible desarrollar Software con cero acoplamiento! Sin embargo, mediante algunas técnicas es posible reducirlo!

Spring Framework fomenta el débil acoplamiento mediante la Inyección de dependencias que es lo siguiente que veremos.

Inyección de la Dependencia

La Inyección de la dependencia sigue un sencillo principio, "No me llames, YO te llamo". Lo anterior describe perfectamente la tarea de la DI (Dependency Injection), es decir, cuando desarrollamos Software, sabemos de antemano que existen clases relacionadas, cada objeto se hace responsable de llamar y crear a otros objetos que necesita para poder llevar a cabo su tarea. Para aclarar lo anterior vamos a realizar el ya clásico programa del "Hola Mundo!". Utilizaremos NetBeans 6.8 por su sencillez y simplicidad de primera mano (omitiremos su lentitud), desde luego que Eclipse es un mejor IDE, pero en Eclipse debemos instalar un plugin para trabajar más cómodamente con Spring y NetBeans ya lo trae por defecto (por ello utilice el término "de primera mano").

En NetBeans creamos un proyecto web y llegado a la opción de Frameworks, seleccionamos Spring Web MVC.

Vamos a crear una interfaz llamada ISaludo:

public interface ISaludo {

    void saludar();

}

Así como la clase que implemente la interfaz:

public class Saludo implements ISaludo{
    public String mensaje;

    public Saludo(String mensaje){
        this.mensaje = mensaje;
    }
    public void saludar() {
        System.out.println(mensaje);
    }
}

Vemos que la clase Saludo recibe una cadena en su constructor, esto podría ser  otro tipo de Objeto creado por nosotros mismos. Lo que vamos a hacer aquí es tan sencillo que no se le vera utilidad a nivel de aplicación y en realidad, mucho del poder de Spring puede ser visto con mayor facilidad a nivel de Arquitectura! Vamos a concentrarnos en aplicar la DI.

Dentro de la carpeta WEB-INF, NetBeans ha creado un archivo XML llamado applicationContext.xml, en el tendremos a las etiquetas y dentro de ellas colocaremos lo siguiente:


        
El pequeño fragmento anterior, tendrá la tarea de instanciar un objeto de tipo Saludo (véase que esta dentro del paquete saludo), a este objeto lo vamos a referenciar por "beanSaludo". Además podemos ver que la clase Saludo recibe en su constructor una cadena de texto, misma que inyectaremos desde Spring mediante el atributo constructor-arg. Finalmente creamos una clase para ejecutar este ejemplo, el más sencillo de todos los que pueda haber!

public class SaludoTest {

    public static void main(String args[]){
        BeanFactory context=
                new XmlBeanFactory(new 
                FileSystemResource("AQUI LA RUTA/applicationContext.xml"));

        ISaludo saludo = (ISaludo) context.getBean("beanSaludo");
        saludo.saludar();
    }

}
Al ejecutar la clase anterior, podremos observar en la consola de NetBeans la siguiente salida:

 "Hola, este es nuestro primer ejemplo DI!!" 

 Lo primero a resaltar es que dicho mensaje no ha sido establecido! Podría pensarse en primera instancia que hubiera sido lo mismo colocar el mensaje en algún archivo de texto pero en realidad si lo hubiéramos hecho así, en algún lugar del código tendríamos que leer el archivo obtener el valor y "settearlo" al atributo mensaje de la clase Saludo! Sin embargo, nótese que en este sencillo ejemplo, Spring ha INYECTADO dicho recurso automáticamente por nosotros, es decir, nosotros no hemos hecho nada como esto:

Saludo saludo = new Saludo("hola mundo!");  

ni tampoco

saludo.setMensaje("Hola mundo"); 

Lo que se debe notar es que Spring como por arte de magia a inyectado el recurso (la cadena de texto) por nosotros! Sin aplicar la DI, el código del método main quedaria mucho más simple:

public class SaludoTest {
    public static void main(String args[]){
        Saludo saludo = new 
               Saludo("Hola, este es nuestro primer ejemplo DI!!");
        saludo.saludar();
    }

}

Con el código anterior, obtendriamos el mismo resultado pero sin la utilización de Spring! Este ejemplo es tan sencillo que el poder de la DI no es notoria, al contrario, lo hace ver como algo inútil, sin embargo, este ejemplo es meramete educativo y debe bastar para entender a que se refiere la "Inyección de la Dependencia" (NO me llames, YO te llamo). Más adelante veremos ejemplos más útiles en donde se vera de mejor forma la utilidad de la DI.

Saludos!!


Cualquier error encontrado en este tutorial, reportarlo como comentario dentro del mismo!
La información contenida aquí se utiliza con fines educativos y su utilización en ambientes de producción es únicamente responsabilidad de quien lo hace.

4 comentarios:

Alejandro dijo...

hola sabes que al momento de ejecutar el proyecto me sale este error y aun desconozco porque

eps-ear-jar:
deps-jar:
library-inclusion-in-archive:
Copying 1 file to C:\Documents and Settings\alejandrofq\Escritorio\Saludo\build\web\WEB-INF\lib
Copying 1 file to C:\Documents and Settings\alejandrofq\Escritorio\Saludo\build\web\WEB-INF\lib
library-inclusion-in-manifest:
compile:
compile-jsps:
In-place deployment at C:\Documents and Settings\alejandrofq\Escritorio\Saludo\build\web
deploy?config=file%3A%2FC%3A%2FDOCUME%7E1%2FALEJAN%7E1%2FCONFIG%7E1%2FTemp%2Fcontext5063904100768969528.xml&path=/Saludo
FAIL - Deployed application at context path /Saludo but context failed to start
C:\Documents and Settings\alejandrofq\Escritorio\Saludo\nbproject\build-impl.xml:584: The module has not been deployed.
BUILD FAILED (total time: 2 seconds)

Ascari Romo dijo...

Lo más fácil para evitar que batalles es que tu mismo desde NetBeans generes un nuevo proyecto Spring y sustituir el código de los archivos descritos en el artículo.

Saludos!!

Shadonwk dijo...

Hola Brother, exelente tuto, una duda, en la opcion de frameworks tambien me pide un servidor, yo tengo apache, esta bien seleccionarlo?
otra pregunta el netbeans que tengo maneja la version 2.5 de spring, como se actualizaria a la version 3?

Saludos.

Ascari Romo dijo...

La versión 3 aún no la he probado, se que cambio un poco en la distribución de las librerías.

Saludos!!

Publicar un comentario