Las palabras invert
o control
no se utilizan en absoluto para definir la Inversión de Control en las definiciones que he visto.
Definiciones
Wikipedia
La inversión de control (IoC) es una técnica de programación, expresada aquí en términos de programación orientada a objetos, en la que el acoplamiento de objetos está limitado en tiempo de ejecución por un objeto ensamblador y normalmente no se conoce en tiempo de compilación mediante análisis estático. ~ http://en.wikipedia.org/wiki/Inversion_of_control
Martin Fowler
La inversión de control es un patrón común en la comunidad Java que ayuda a conectar contenedores livianos o ensamblar componentes de diferentes proyectos en una aplicación cohesiva. ~ basado en http://www.martinfowler.com/articles/injection.html (redactado nuevamente)
Entonces, ¿por qué la Inversión de control se llama Inversión de control? ¿Qué control se invierte y por qué? ¿Hay alguna manera de definir la Inversión de Control usando la terminología: invertir y controlar ?
fuente
Respuestas:
Digamos que tiene algún tipo de clase de "repositorio", y ese repositorio es responsable de entregarle los datos de una fuente de datos.
El repositorio podría establecer una conexión con la fuente de datos por sí mismo. Pero, ¿y si le permitiera pasar una conexión a la fuente de datos a través del constructor del repositorio?
Al permitir que la persona que llama proporcione la conexión, ha desacoplado la dependencia de conexión de la fuente de datos de la clase de repositorio, permitiendo que cualquier fuente de datos trabaje con el repositorio, no solo la especificada por el repositorio.
Ha invertido el control al transferir la responsabilidad de crear la conexión desde la clase de repositorio a la persona que llama.
Martin Fowler sugiere utilizar el término "Inyección de dependencias" para describir este tipo de Inversión de control, ya que la Inversión de control como concepto puede aplicarse de manera más amplia que simplemente inyectar dependencias en un método de constructor.
fuente
No creo que nadie pueda explicarlo mejor que Martin Fowler, más abajo en el artículo al que se vinculó .
Como explica en los párrafos anteriores, esto no es exactamente lo mismo que la razón por la cual se originó el término "Inversión de control".
Es por eso que continúa acuñando el término "Inyección de dependencia" para cubrir esta implementación específica de Inversión de control.
Para aclarar un poco: Inversión de control significa cualquier cosa que invierta la estructura de control de un programa desde el diseño de procedimiento clásico.
En días anteriores, un ejemplo clave de esto era dejar que un marco manejara la comunicación entre una IU y su código, en lugar de dejar su código para generar la IU directamente.
En tiempos más recientes (cuando tales marcos dominaban bastante, por lo que la pregunta ya no era relevante), un ejemplo fue invertir el control sobre la creación de instancias de objetos.
Fowler y otros decidieron que el término Inversión de control abarcaba demasiadas técnicas y que necesitábamos un nuevo término para el ejemplo específico de creación de instancias de objetos (Inyección de dependencia) pero, para cuando se llegó a un acuerdo, la frase "Contenedor IoC "había despegado.
Esto enturbia mucho el agua, porque un contenedor de IoC es un tipo específico de inyección de dependencia, pero la inyección de dependencia es un tipo específico de inversión de control. Es por eso que obtienes respuestas tan confusas, sin importar dónde mires.
fuente
Aquí están los programas de flujo de control "regulares" que generalmente se siguen:
La inversión de Control "invierte" ese flujo de control, lo que significa que lo invierte:
Esa última línea es la importante. En lugar de llamar a alguien más cuando lo desee, alguien más lo llamará cuando lo desee.
Un ejemplo común de esto son los marcos web como Rails. Usted define Controladores, pero en realidad no decide cuándo se llaman. Rails los llama cuando decide que hay una necesidad.
fuente
Se trata de quién controla la creación de instancias de dependencias.
Tradicionalmente, cuando una clase / método necesita usar otra clase (dependencia), la clase / método lo instancia directamente. Controla sus dependencias.
Con Inversion of Control (IoC), la persona que llama pasó la dependencia, por lo tanto, crea una instancia de la dependencia. La persona que llama controla las dependencias.
El control de dónde se instancia una dependencia se ha invertido; en lugar de estar en la "parte inferior", donde está el código que lo necesita, se instancia en la "parte superior", donde se llama al código que lo necesita.
fuente
Por lo general, las llamadas de código de nivel superior (es decir, los controles) son de código de nivel inferior. Main () llama a function (), function () llama a libraryFunction ().
Eso se puede invertir, por lo que la función de biblioteca de bajo nivel en la parte inferior llama a funciones de nivel superior.
¿Por qué harías eso? Middleware A veces quieres controlar el nivel superior y el nivel inferior, pero hay mucho trabajo en el medio que simplemente no quieres hacer. Tome la implementación de quicksort en C stdlib . Llamas a quicksort en el nivel superior. Usted le da a qsort () un puntero de función a su propia función que implementa un comparador en lo que desee. Cuando se llama qsort (), llama a esta función de comparación. qsort () está controlando / llamando / manejando su función de alto nivel.
fuente
Aquí hay una descripción general simple:
En los viejos tiempos, el control era propiedad de la aplicación primero y el usuario segundo. Si la aplicación necesitaba algo del usuario, se detendría y preguntaría y luego pasaría a su siguiente tarea. La interacción del usuario proporcionó principalmente datos en lugar de controlar lo que la aplicación hizo a continuación. Esto es un poco extraño para nosotros hoy en día, ya que no vemos este tipo de comportamiento muy a menudo.
Si cambiamos eso y le damos al usuario el control primario, entonces hemos invertido el control. Esto significa que, en lugar de que el usuario espere a que la aplicación le dé algo que hacer, la aplicación se queda esperando a que el usuario le dé algo que hacer. Las GUI son un gran ejemplo de esto y casi todo lo que tenga un bucle de eventos ha invertido el control.
Tenga en cuenta que mi ejemplo está en el nivel superior y que este concepto de inversión de control puede abstraerse a diferentes capas de control dentro de la aplicación (es decir, inyección de dependencia). Esta puede ser la razón por la cual es tan difícil obtener una respuesta directa.
fuente
Tratemos de entenderlo a través de los dos ejemplos.
Ejemplo 1
En días anteriores, las aplicaciones solían generar indicaciones de comando para aceptar entradas de usuario una tras otra. Hoy en día, los marcos de la interfaz de usuario crean instancias de varios elementos de la interfaz de usuario, recorren varios eventos de esos elementos de la interfaz de usuario (como pasar el mouse, hacer clic, etc.) y los programas de usuario / principal proporcionan ganchos (por ejemplo, oyentes de eventos de la interfaz de usuario en Java) para escuchar esos eventos. Por lo tanto, el "control" del flujo de elementos de la interfaz de usuario principal se mueve del programa de usuario al marco de la interfaz de usuario. En días anteriores, estaba en el programa de usuario.
Ejemplo 2
Considere la clase a
CustomerProcessor
continuación:Si quiero
processCustomer()
ser independiente de cualquier implementacióngetAllCusts()
, no solo de la proporcionada porSqlCustRepo
, tendré que deshacerme de la línea:SqlCustRepo custRepo = new SqlCustRepo()
y reemplazarla con algo más genérico, capaz de aceptar un tipo variado de implementación, de modo queprocessCustomers()
simplemente funcione para cualquier implementación provista. El código anterior (instanciando la clase requeridaSqlCustRepo
por la lógica del programa principal) es una forma tradicional y no logra este objetivo de desacoplarseprocessCustomers()
de la implementación degetAllCusts()
. En la inversión de control, el contenedor crea una instancia de la clase de implementación requerida (como se especifica por, digamos, la configuración xml), la inyecta en la lógica principal del programa que se enlaza según los ganchos especificados (por ejemplo, por@Autowired
anotación ogetBean()
método en Spring Framework).Veamos cómo se puede hacer esto. Considere el siguiente código.
Config.xml
CustRepo.java
JsonCustRepo.java
App.java
También podemos tener
y
y no necesitaremos cambiar App.java.
Por encima del contenedor (que es el marco de Spring) tiene la responsabilidad de escanear el archivo xml, instanciar el bean de tipo específico e inyectarlo en el programa del usuario. El programa de usuario no tiene control sobre qué clase se instancia.
PD: IoC es un concepto genérico y se logra de muchas maneras. Los ejemplos anteriores lo logran mediante inyección de dependencia.
Referencia: artículo de Martin Fowler .
fuente