Según el artículo escrito por Martin Fowler , la inversión de control es el principio en el que se invierte el flujo de control de un programa: en lugar de que el programador controle el flujo de un programa, las fuentes externas (marco, servicios, otros componentes) toman el control de eso. Es como si conectamos algo a otra cosa. Mencionó un ejemplo sobre EJB 2.0:
Por ejemplo, la interfaz Session Bean define ejbRemove, ejbPassivate (almacenado en el almacenamiento secundario) y ejbActivate (restaurado del estado pasivo). No puedes controlar cuándo se llaman estos métodos, solo lo que hacen. El contenedor nos llama, nosotros no lo llamamos.
Esto lleva a la diferencia entre framework y biblioteca:
La inversión del control es una parte clave de lo que hace que un marco sea diferente a una biblioteca. Una biblioteca es esencialmente un conjunto de funciones a las que puede llamar, en estos días generalmente organizadas en clases. Cada llamada hace algo de trabajo y devuelve el control al cliente.
Creo que el punto de vista de que DI es IOC significa que la dependencia de un objeto está invertida: en lugar de controlar sus propias dependencias, ciclo de vida ... algo más lo hace por usted. Pero, como me contó sobre la DI a mano, la DI no es necesariamente un COI. Todavía podemos tener DI y no IOC.
Sin embargo, en este documento (de pococapsule, otro IOC Framework para C / C ++), sugiere que debido a IOC y DI, los contenedores IOC y los marcos DI son mucho más superiores a J2EE, ya que J2EE mezcla el código marco en los componentes , por lo que no lo convierte en Objeto Java / C ++ simple (POJO / POCO)
Inversión de contenedores de control que no sean el patrón de inyección de dependencia (enlace de archivo)
Lectura adicional para comprender cuál es el problema con el antiguo Marco de desarrollo basado en componentes, que conduce al segundo documento anterior: Por qué y qué de la Inversión de control (Enlace de archivo)
Mi pregunta : ¿Qué es exactamente COI y DI? Estoy confundido. Basado en pococapsule, IOC es algo más significativo que la simple inversión del control entre objetos o programadores y marcos.
Respuestas:
IoC es un término genérico que significa que en lugar de que la aplicación llame a los métodos en un marco, el marco llama a las implementaciones proporcionadas por la aplicación.
DI es una forma de IoC, donde las implementaciones se pasan a un objeto a través de búsquedas de constructores / establecedores / servicios, de las cuales el objeto 'dependerá' para comportarse correctamente.
IoC sin usar DI , por ejemplo, sería el patrón de Plantilla porque la implementación solo se puede cambiar a través de subclases.
Los Frameworks DI están diseñados para hacer uso de DI y pueden definir interfaces (o Anotaciones en Java) para facilitar el paso de las implementaciones.
Los IoC Containers son marcos de trabajo DI que pueden funcionar fuera del lenguaje de programación. En algunos, puede configurar qué implementaciones usar en los archivos de metadatos (por ejemplo, XML) que son menos invasivos. Con algunos puedes hacer IoC que normalmente sería imposible como inyectar una implementación en los puntos de corte .
Vea también este artículo de Martin Fowler .
fuente
En resumen, IoC es un término mucho más amplio que incluye, entre otros, DI
El término Inversión de control (IoC) originalmente significaba cualquier tipo de estilo de programación donde un marco general o tiempo de ejecución controlaba el flujo del programa
Antes de que DI tuviera un nombre, las personas comenzaron a referirse a los marcos que gestionan las dependencias como inversión de contenedores de control, y pronto, el significado de IoC se desvió gradualmente hacia ese significado particular: inversión de control sobre dependencias.
La inversión de control (IoC) significa que los objetos no crean otros objetos en los que confían para hacer su trabajo. En cambio, obtienen los objetos que necesitan de una fuente externa (por ejemplo, un archivo de configuración xml).
La inyección de dependencia (DI) significa que esto se realiza sin la intervención del objeto, generalmente mediante un componente de marco que pasa los parámetros del constructor y establece las propiedades.
fuente
fuente
COI ( I nVersión o f C ontrol): - Es un término genérico e implementado de varias formas (eventos, delegados, etc.).
DI ( D ependency I njection): - DI es un subtipo de IoC y se implementa mediante inyección de constructor, inyección de setter o inyección de interfaz .
Pero Spring solo admite los siguientes dos tipos:
NullPointerException: bean does not exist
. La inyección de constructor es la mejor práctica para inyectar dependencias.fuente
DI es un subconjunto de IoC
Aquí hay algunas otras técnicas para lograr IoC .
fuente
IOC (Inversión de control) : dar control al contenedor para obtener una instancia del objeto se llama Inversión de control, significa que en lugar de crear un objeto con el nuevo operador, deje que el contenedor lo haga por usted.
DI (inyección de dependencia) : la forma de inyectar propiedades a un objeto se llama inyección de dependencia .
Tenemos tres tipos de inyección de dependencia :
Spring solo admite la inyección de constructor y la inyección de setter / getter .
fuente
Como todas las respuestas enfatizan la teoría, me gustaría demostrar con un primer enfoque de ejemplo:
Supongamos que estamos creando una aplicación que contiene una función para enviar mensajes de confirmación por SMS una vez que se ha enviado el pedido. Tendremos dos clases, una es responsable de enviar el SMS (SMSService) y otra responsable de capturar las entradas del usuario (UIHandler), nuestro código se verá a continuación:
La implementación anterior no está mal, pero hay algunos problemas:
-) Suponga que en el entorno de desarrollo, desea guardar los SMS enviados a un archivo de texto en lugar de usar la puerta de enlace de SMS, para lograr esto; terminaremos cambiando la implementación concreta de (SMSService) con otra implementación, estamos perdiendo flexibilidad y nos vemos obligados a reescribir el código en este caso.
-) Terminaremos mezclando las responsabilidades de las clases, nuestro (UIHandler) nunca debe saber acerca de la implementación concreta de (SMSService), esto debe hacerse fuera de las clases usando "Interfaces". Cuando se implementa esto, nos dará la capacidad de cambiar el comportamiento del sistema intercambiando el (SMSService) utilizado con otro servicio simulado que implementa la misma interfaz, este servicio guardará los SMS en un archivo de texto en lugar de enviarlo a mobileNumber.
Para solucionar los problemas anteriores, utilizamos interfaces que serán implementadas por nuestro (SMSService) y el nuevo (MockSMSService), básicamente la nueva interfaz (ISMSService) expondrá los mismos comportamientos de ambos servicios como el código a continuación:
Luego cambiaremos nuestra implementación (SMSService) para implementar la interfaz (ISMSService):
Ahora podremos crear un nuevo servicio de simulación (MockSMSService) con una implementación totalmente diferente usando la misma interfaz:
En este punto, podemos cambiar el código en (UIHandler) para usar la implementación concreta del servicio (MockSMSService) fácilmente de la siguiente manera:
Hemos logrado mucha flexibilidad e implementado la separación de preocupaciones en nuestro código, pero aún necesitamos hacer un cambio en la base del código para cambiar entre los dos Servicios de SMS. Entonces, necesitamos implementar la inyección de dependencia .
Para lograr esto, necesitamos implementar un cambio en nuestro constructor de clase (UIHandler) para pasar la dependencia a través de él, al hacer esto, el código que usa (UIHandler) puede determinar qué implementación concreta de (ISMSService) usar:
Ahora el formulario de interfaz de usuario que hablará con la clase (UIHandler) es responsable de pasar qué implementación de interfaz (ISMSService) consumir. Esto significa que hemos invertido el control, el (UIHandler) ya no es responsable de decidir qué implementación usar, lo hace el código de llamada. Hemos implementado el principio de Inversión de control , que es un tipo de DI.
El código del formulario de la interfaz de usuario será el siguiente:
fuente
Pero la documentación de primavera dice que son lo mismo.
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction
En la primera línea " IoC también se conoce como inyección de dependencia (DI) ".
fuente
IoC - Inversión de control es un término genérico, independiente del lenguaje, en realidad no es crear los objetos sino describir en qué objeto de moda se está creando.
DI - Inyección de dependencias es un término concreto, en el que proporcionamos dependencias del objeto en tiempo de ejecución mediante el uso de diferentes técnicas de inyección, a saber. Setter Injection, Constructor Injection o por Interface Injection.
fuente
La inversión de control es un paradigma de diseño con el objetivo de dar más control a los componentes específicos de su aplicación, los que realizan el trabajo.
La inyección de dependencia es un patrón utilizado para crear instancias de objetos de los que dependen otros objetos sin saber en el momento de la compilación qué clase se utilizará para proporcionar esa funcionalidad.
Existen varias técnicas básicas para implementar la inversión de control. Estos son:
1). Un constructor de inyección
2). Una inyección de setter
3). Una inyección de interfaz
fuente
DI e IOC son dos patrones de diseño que se centran principalmente en proporcionar un acoplamiento suelto entre componentes , o simplemente una forma en la que desacoplamos las relaciones de dependencia convencionales entre objetos para que los objetos no estén unidos entre sí.
Con los siguientes ejemplos, estoy tratando de explicar estos dos conceptos.
Anteriormente estamos escribiendo código como este
Con la inyección de dependencia, el inyector de dependencia se encargará de la creación de instancias de los objetos.
El proceso anterior de otorgar el control a otro (por ejemplo, el contenedor) para la creación de instancias y la inyección puede denominarse Inversion of Control y el proceso en el que el contenedor IOC inyecta la dependencia para nosotros puede denominarse inyección de dependencia.
El COI es el principio en el que se invierte el flujo de control de un programa: en lugar de que el programador controle el flujo de un programa , el programa controla el flujo al reducir la sobrecarga al programador, y el proceso utilizado por el programa para inyectar dependencia se denomina DI
Los dos conceptos trabajan juntos y nos proporcionan una forma de escribir código mucho más flexible, reutilizable y encapsulado, lo que los convierte en conceptos importantes en el diseño de soluciones orientadas a objetos.
También recomiendo leer.
¿Qué es la inyección de dependencia?
También puedes consultar una de mis respuestas similares aquí
Diferencia entre inversión de control e inyección de dependencia
fuente
La inversión de control es un principio de diseño genérico de la arquitectura de software que ayuda a crear marcos de software modulares reutilizables que son fáciles de mantener.
Es un principio de diseño en el que el flujo de control se "recibe" de la biblioteca genérica escrita o del código reutilizable.
Para entenderlo mejor, veamos cómo solíamos codificar en nuestros primeros días de codificación. En los lenguajes de procedimiento / tradicionales, la lógica empresarial generalmente controla el flujo de la aplicación y "llama" al código / funciones genéricos o reutilizables. Por ejemplo, en una aplicación de consola simple, mi flujo de control está controlado por las instrucciones de mi programa, que pueden incluir las llamadas a algunas funciones reutilizables generales.
En contraste, con IoC, los Frameworks son el código reutilizable que "llama" a la lógica de negocios.
Por ejemplo, en un sistema basado en Windows, un marco ya estará disponible para crear elementos de la interfaz de usuario como botones, menús, ventanas y cuadros de diálogo. Cuando escribo la lógica de negocios de mi aplicación, serían los eventos del marco los que llamarán a mi código de lógica de negocios (cuando se dispara un evento) y NO lo contrario.
Aunque, el código del marco no tiene conocimiento de mi lógica comercial, todavía sabrá cómo llamar a mi código. Esto se logra utilizando eventos / delegados, devoluciones de llamada, etc. Aquí el control de flujo se "invierte".
Por lo tanto, en lugar de depender del flujo de control de los objetos enlazados estáticamente, el flujo depende del gráfico general del objeto y de las relaciones entre los diferentes objetos.
La inyección de dependencias es un patrón de diseño que implementa el principio de IoC para resolver dependencias de objetos.
En palabras más simples, cuando intente escribir código, creará y usará diferentes clases. Una clase (Clase A) puede usar otras clases (Clase B y / o D). Entonces, las clases B y D son dependencias de la clase A.
Una analogía simple será un auto de clase. Un automóvil puede depender de otras clases como motor, neumáticos y más.
La inyección de dependencia sugiere que, en lugar de que las clases dependientes (Class Car aquí) creen sus dependencias (Class Engine y class Tire), la clase debería ser inyectada con la instancia concreta de la dependencia.
Vamos a entender con un ejemplo más práctico. Considere que está escribiendo su propio TextEditor. Entre otras cosas, puede tener un corrector ortográfico que le brinde al usuario la posibilidad de revisar los errores tipográficos en su texto. Una implementación simple de dicho código puede ser:
A primera vista, todo parece rosado. El usuario escribirá algo de texto. El desarrollador capturará el texto y llamará a la función CheckSpellings y encontrará una lista de errores tipográficos que le mostrará al usuario.
Todo parece funcionar muy bien hasta un buen día cuando un usuario comienza a escribir francés en el Editor.
Para proporcionar soporte para más idiomas, necesitamos tener más correctores ortográficos. Probablemente francés, alemán, español, etc.
Aquí, hemos creado un código estrechamente acoplado con SpellChecker "inglés" estrechamente acoplado con nuestra clase TextEditor, lo que significa que nuestra clase TextEditor depende de EnglishSpellChecker o, en otras palabras, EnglishSpellCheker es la dependencia de TextEditor. Necesitamos eliminar esta dependencia. Además, nuestro editor de texto necesita una forma de mantener la referencia concreta de cualquier corrector ortográfico basado en el criterio del desarrollador en tiempo de ejecución.
Entonces, como vimos en la introducción de DI, sugiere que la clase debería ser inyectada con sus dependencias. Por lo tanto, debería ser responsabilidad del código de llamada inyectar todas las dependencias a la clase / código llamado. Entonces podemos reestructurar nuestro código como
En nuestro ejemplo, la clase TextEditor debería recibir la instancia concreta del tipo ISpellChecker.
Ahora, la dependencia se puede inyectar en Constructor, una Propiedad pública o un método.
Intentemos cambiar nuestra clase usando Constructor DI. La clase TextEditor modificada se verá así:
Para que el código de llamada, al crear el editor de texto, pueda inyectar el tipo de corrector ortográfico apropiado en la instancia del editor de texto.
Puedes leer el artículo completo aquí.
fuente
IOC (Inversión de control): dar control al contenedor para obtener la instancia del objeto se llama Inversión de control. Significa que, en lugar de crear un objeto con un nuevo operador , deje que el contenedor lo haga por usted.
DI (Inyección de dependencia): Pasar los parámetros (propiedades) requeridos desde XML a un objeto (en POJO CLASS) se llama inyección de dependencia.
fuente
IOC indica que las clases externas que administran las clases de una aplicación, y las clases externas significan que un contenedor administra la dependencia entre la clase de la aplicación. El concepto básico de IOC es que el programador no necesita crear sus objetos, sino que describe cómo deben crearse.
Las tareas principales que realiza el contenedor IoC son: crear una instancia de la clase de aplicación. para configurar el objeto. para ensamblar las dependencias entre los objetos.
DI es el proceso de proporcionar las dependencias de un objeto en tiempo de ejecución mediante la inyección de setter o la inyección de constructor.
fuente
IOC (Inversion of Control) es básicamente un concepto de patrón de diseño para eliminar dependencias y desacoplarlas para hacer que el flujo no sea lineal, y permite que el contenedor u otra entidad gestione el aprovisionamiento de dependencias. De hecho, sigue al director de Hollywood "No nos llames, te llamaremos". Entonces resumiendo las diferencias.
Inversión de control: - Es un término genérico para desacoplar las dependencias y delegar su aprovisionamiento, y esto se puede implementar de varias maneras (eventos, delegados, etc.).
Inyección de dependencia: - DI es un subtipo de IOC y se implementa mediante inyección de constructor, inyección de setter o inyección de método.
El siguiente artículo describe esto muy claramente.
https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO
fuente
Creo que la idea se puede demostrar claramente sin entrar en malezas orientadas a objetos, que parecen confundir la idea.
Si inclina la cabeza y entrecierra los ojos, verá que DI es una implementación particular de IoC con preocupaciones específicas. En lugar de inyectar modelos y comportamientos en un marco de aplicación u operación de orden superior, está inyectando variables en una función u objeto.
fuente
Comencemos con D de SOLID y veamos DI e IoC del libro de Scott Millett "Patrones de diseño profesional ASP.NET":
Millett, C (2010). Patrones de diseño profesional ASP.NET. Wiley Publishing. 7-8.
fuente
// ICO, DI, hace 10 años, de esta manera:
Ahora con Spring 3,4 o más reciente es como abajo
En general, el control se invierte del antiguo concepto de código acoplado a los marcos como Spring, que hace que el objeto esté disponible. Así que eso es IOC hasta donde yo sé e inyección de dependencia como sabes cuando inyectamos el objeto dependiente en otro objeto usando Constructor o setters. Inyectar básicamente significa pasarlo como argumento. En primavera tenemos una configuración basada en XML y anotaciones donde definimos el objeto bean y pasamos el objeto dependiente con el estilo de inyección de Constructor o setter.
fuente
Encontré el mejor ejemplo en Dzone.com, que es realmente útil para comprender la diferencia real entre COI y DI
Leer artículo completo COI y Leer artículo completo DI
fuente
1) DI es Child-> obj depende de parent-obj. El verbo depende es importante. 2) IOC es Child-> obj realizar bajo una plataforma. donde la plataforma podría ser la escuela, la universidad, la clase de baile. Aquí realizar es una actividad con implicación diferente bajo cualquier proveedor de plataforma.
ejemplo práctico: `
``
-AB
fuente
En cuanto a esta pregunta, diría que el wiki ya ha proporcionado explicaciones detalladas y fáciles de entender. Citaré lo más significativo aquí.
Implementación de IoC
En cuanto a la inyección de dependencia
fuente
El concepto de IoC se escuchó inicialmente durante la era de la programación de procedimientos. Por lo tanto, desde un contexto histórico, IoC habló sobre la inversión de la propiedad del control de flujo es decir, quién es el responsable de invocar las funciones en el orden deseado, ya sean las funciones mismas o si debe invertirlas en alguna entidad externa.
Sin embargo, una vez que surgió la OOP, la gente comenzó a hablar sobre la IoC en el contexto de la OOP, donde las aplicaciones también se ocupan de la creación de objetos y sus relaciones, aparte del flujo de control. Dichas aplicaciones querían invertir la propiedad de la creación de objetos (en lugar del flujo de control) y requerían un contenedor que sea responsable de la creación de objetos, el ciclo de vida del objeto y las dependencias de inyección de los objetos de la aplicación, eliminando así los objetos de la aplicación de la creación de otro objeto concreto.
En ese sentido, DI no es lo mismo que Io C , ya que no se trata de control de flujo, sin embargo, es una especie de Io * , es decir, Inversión de la propiedad de la creación de objetos.
¿Qué hay de malo en mi forma de explicar DI y IoC?
fuente
IoC, también conocido como Inversión de control, se refiere al control de creación de instancias que realiza el contenedor Spring. El control para crear y construir objetos se encarga del contenedor. El contenedor crea los objetos y los inyecta en nuestra aplicación.
fuente