Seguramente muchos de nosotros ya hemos escuchado el término Inversion of control (Inversión de control) más de una vez, incluso otros, ya los están utilizando sin saberlo. Lo cierto es que cada vez es más común escuchar este término y es que ha revolucionado por completo la forma trabar con los Frame Works.
Inversion of control (IoC) es una forma de trabajar que rompe con el formato tradicional, en donde el programar es el encargado de definir la secuencia de operaciones que se deben de realizar para llegar a un resultado. En este sentido el programador debe conocer todos los detalles del framework y las operaciones a realizar en él, por otra parte, el Framework no conoce absolutamente nada de nuestro programa. Es decir, solo expone operaciones para ser ejecutada. La siguiente imagen muestra la forma de trabajo normal.
Veamos que nuestra aplicación es la que llama en todo momento al Framework y este hace lo que la App le solicita. Por otra parte, al Framework no le interesa en absoluto la App.
Pero qué pasaría si invirtiéramos la forma de trabajo, y que en lugar de que la App llame funciones del Framework, sea el Framework el que ejecute operaciones sobre la App, ¿suena extraño no? Pues en realidad a esta técnica es a la que se le conoce como Inversion of Control. Veamos en la siguiente imagen como es que funciona IoC:
Esta última imagen se ve bastante parecida a la anterior, sin embargo, tiene una gran diferencia, y es que las llamadas se invirtieron, ahora es el Framework es el realiza operaciones sobre nuestra App.
Seguramente a estas alturas te pregunta cómo es que un Framework que no conoce tu App y que incluso se compilo desde mucho antes puede realizar operaciones sobre nuestra App. La respuesta es simple pero complicada, y es que utilizar este IoC es mucho más simple de lo que parecería, pero implementar un Framework de este tipo tiene un grado alto de complejidad, dicho de otra manera, si tú eres la App puedes implementar muy fácilmente al Framework, pero si tu estas desarrollando el Framework puede ser un verdadero dolor de cabeza.
Pues bien, IoC se basa en la introspección (en Java llamado Reflection) el cual es un procedimiento por el cual leemos metadatos de la App que nos permita entender cómo funciona, los metadatos pueden estar expresados principalmente de dos formas, la primera es mediante archivos de configuración como XML o con metadados directamente definidos sobre las clases de nuestro programa, en Java estos metadatos son las @Annotations o anotaciones y es por medio de estos metadatos y con técnicas de introspección que es posible entender el funcionamiento de la App.
NOTA: La introspección son técnicas para analizar clases en tiempo de ejecución, mediante esta es posible saber las propiedades, métodos, clases que extiende e implementa, ejecutar operaciones, settear u obtener valores, etc. y todo esto sin saber absolutamente nada de la clase.
Otra de los problemas que intenta solucionar IoC es la de evitar utilizar el operador new para crear clases clave o que son gestionadas por el Framework. En su lugar el Framework creará estos objetos por nosotros y nos podrá a disposición por medio de inyección de dependencias.
Pero analicemos un ejemplo concreto. Imaginemos que crearemos un Framework para gestionar la capa de servicios y la persistencia. Veamos la siguiente clase:
package com.oscarblancarte.ioc; import javax.annotation.Resource; /** * @author Oscar Blancarte */ @Service public class EmployeeService { private TransactionManager tran; public EmployeeService(){} @Resource public void setTransactionManager(TransactionManager tran){ this.tran = tran; } @Transaction public void saveEmployee(Employee emp){ tran.persist(emp); } }
Primero que nada, es importante resaltar que el siguiente ejemplo ilustrativo por lo que no tiene porque no te funcionara si lo tratas de compilar. Ya con esa aclaración, analicemos el ejemplo. Lo primero que vemos es una clase anotada con @Service, esto le indicara a nuestro Framework que es una clase se servicios y que debe de ser gestionada por él, la segundo que vemos es el método setTransactionManager el cual recibe un objeto de tipo TransactionManager, el método esta anotado con @Resource, lo que le indita al Framework que ese método debe de ser utilizado para inyectar un TransactionManager. Finalmente vemos el método saveEmployee, el cual esta anotado con @Transaction lo que le indicara al Framework que todo lo que se realice en ese método debe de ser trabajado bajo una transacción, el método recibe el empleado a guardar.
Ya con la explicación de la clase vemos a entrar en algunos detalles importantes. Primero que nada, esta clase deberá ser instanciada únicamente por Framework, ya que este al crear la instancia ejecutará el método setTransactionManager para establecer un valor a la variable tran. Seguido cuando el método saveEmployee sea ejecutado será el Framework quien abra la transacción por nosotros y la cerrar cuando la ejecución del este termine. Finalmente, cuando el servicio ya no sea requerido será destruido de forma automática y los recursos como Conexiones a base de datos serán liberadas. Veamos la siguiente imagen para entender que está pasando:
Analicemos la imagen, primero el Framework analizará al App mediante los metadatos, este encontrará la clase EmployeeService que esta anotada con @Service, seguido le inyectará una instancia del TrasnactionManager mediante el método setTransactionManager que esta anotado con @Resource, finalmente el servicio será retornado a la App para ser utilizado.
Cabe mencionar que los proxys son clave para controlar como la forma en que el usuario utiliza las operaciones. Puedes encontrar mucho más de este patrón en mi libro.
¿Pero qué pasaría si nos brincamos el Framework y creamos manualmente la clase? Bueno la respuesta es clara, la variable tran no será inyectada y valdrá null, seguido la transaccionalidad del método saveEmployee no servirá de nada, pues solo tendrá un metadato que nadie utiliza.
Bueno, eso ha sido una pequeña introducción al concepto de Inversion of Control, espero que sea lo suficiente mente claro, pues el concepto y sobre todo la implementación pueden llegar a ser complejas.
Super claro muchas gracias por el aporte
Gracias por el comentario Juan, te mando un saludo.
Explicado de una forma muy facil de entender, saludos …
Gracias por el comentario Arturo 🙂
IoC … pocas veces 3 letras esconden tanta complejidad!
Pero con tu aportación lo he entendido mucho mejor!
Gracias!
Gracias por el comentario José 🙂
Llegue aquí, pero no lo entendí a la primera, entonces busque videos, otras lecturas, y luego volví y si pude entender, de la Inversión of control, es decir a modo de comparación mas real, es como una IA, por ejemplo nosotros ya conducimos, sino en el caso de Auto Tesla, toma el control por nosotros, lo mismo sucede con Spring, al declarar las anotaciones en cada clase o método, Spring lee estos metadatos y es como si tuviera el control (Auto Tesla).
se entiende claramente, tengo una pregunta osea que si yo instancio desde la el framework automaticamente este ya no tiene acceso a los metadatos de la App?