oop - injection - ioc spring




¿Qué es la inversión de control? (20)

La inversión de control (o IoC) puede ser bastante confusa cuando se encuentra por primera vez.

  1. ¿Qué es?
  2. ¿Qué problema resuelve?
  3. ¿Cuándo es apropiado usar y cuándo no?

  1. Así que el número 1 above . above

  2. El mantenimiento es la cosa número uno que me resuelve. Garantiza que estoy usando interfaces para que dos clases no sean íntimas entre sí.

Al usar un contenedor como Castle Windsor, resuelve los problemas de mantenimiento incluso mejor. Ser capaz de intercambiar un componente que va a una base de datos por una que utiliza la persistencia basada en archivos sin cambiar una línea de código es impresionante (cambio de configuración, listo).

Y una vez que te metes en los genéricos, se pone aún mejor. Imagina tener un editor de mensajes que recibe registros y publica mensajes. No importa lo que publique, pero necesita un asignador para llevar algo de un registro a un mensaje.

public class MessagePublisher<RECORD,MESSAGE>
{
    public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
    {
      //setup
    }
}

Lo escribí una vez, pero ahora puedo insertar muchos tipos en este conjunto de códigos si publico diferentes tipos de mensajes. También puedo escribir asignadores que toman un registro del mismo tipo y los asignan a diferentes mensajes. El uso de DI con Genéricos me ha dado la capacidad de escribir muy poco código para realizar muchas tareas.

Ah, sí, hay problemas de comprobabilidad, pero son secundarios a los beneficios de IoC / DI.

Definitivamente estoy amando IoC / DI.

3. Se vuelve más apropiado en el momento en que tiene un proyecto de tamaño medio con algo más de complejidad. Yo diría que se vuelve apropiado en el momento en que empiezas a sentir dolor.


  1. La inversión de control es un patrón utilizado para desacoplar componentes y capas en el sistema. El patrón se implementa a través de la inyección de dependencias en un componente cuando se construye. Estas dependencias generalmente se proporcionan como interfaces para un mayor desacoplamiento y para soportar la capacidad de prueba. Los contenedores IoC / DI como Castle Windsor, Unity son herramientas (bibliotecas) que se pueden usar para proporcionar IoC. Estas herramientas proporcionan funciones extendidas que van más allá de la simple administración de dependencias, incluida la vida útil, AOP / Intercepción, política, etc.

  2. a. Evita que un componente sea responsable de administrar sus dependencias.
    segundo. Proporciona la capacidad de intercambiar implementaciones de dependencia en diferentes entornos.
    do. Permite probar un componente mediante simulación de dependencias.
    re. Proporciona un mecanismo para compartir recursos a través de una aplicación.

  3. a. Crítico cuando se hace un desarrollo guiado por pruebas. Sin IoC puede ser difícil de probar, porque los componentes bajo prueba están altamente acoplados al resto del sistema.
    segundo. Crítico en el desarrollo de sistemas modulares. Un sistema modular es un sistema cuyos componentes pueden reemplazarse sin necesidad de recompilación.
    do. Es crítico si hay muchas inquietudes transversales que deben abordarse, en parte en una aplicación empresarial.


Encontré un ejemplo muy claro here que explica cómo el 'control está invertido'.

Código clásico (sin inyección de dependencia)

Aquí es cómo un código que no usa DI funcionará más o menos:

  • La aplicación necesita Foo (por ejemplo, un controlador), por lo que:
  • La aplicación crea Foo
  • La aplicación llama a Foo
    • Foo necesita Bar (por ejemplo, un servicio), por lo que:
    • Foo crea barra
    • Foo llama a Bar
      • Bar necesita Bim (un servicio, un repositorio, ...), así que:
      • Bar crea Bim
      • Bar hace algo

Uso de inyección de dependencia

Aquí es cómo un código con DI funcionará aproximadamente:

  • La aplicación necesita Foo, que necesita Bar, que necesita Bim, así que:
  • La aplicación crea Bim
  • La aplicación crea Bar y le da Bim.
  • La aplicación crea Foo y le da Bar.
  • La aplicación llama a Foo
    • Foo llama a Bar
      • Bar hace algo

El control de las dependencias se invierte de una llamada a la llamada.

¿Qué problemas resuelve?

La inyección de dependencia facilita el intercambio con las diferentes implementaciones de las clases inyectadas. Si bien la prueba unitaria puede inyectar una implementación ficticia, hace que la prueba sea mucho más fácil.

Ejemplo: Supongamos que su aplicación almacena el archivo cargado por el usuario en Google Drive, con DI el código de su controlador puede tener este aspecto:

class SomeController
{
    private $storage;

    function __construct(StorageServiceInterface $storage)
    {
        $this->storage = $storage;
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

class GoogleDriveService implements StorageServiceInterface
{
    public function authenticate($user) {}
    public function putFile($file) {}
    public function getFile($file) {}
}

Cuando sus requisitos cambien, por ejemplo, en lugar de GoogleDrive, se le solicita que utilice Dropbox. Solo necesita escribir una implementación de Dropbox para StorageServiceInterface. No debe realizar ningún cambio en el controlador siempre que la implementación de Dropbox se adhiera a StorageServiceInterface.

Mientras realiza la prueba, puede crear el simulacro del StorageServiceInterface con la implementación ficticia donde todos los métodos devuelven el valor nulo (o cualquier valor predefinido según su requisito de prueba).

En cambio, si tuviera la clase de controlador para construir el objeto de almacenamiento con la new palabra clave como esta:

class SomeController
{
    private $storage;

    function __construct()
    {
        $this->storage = new GoogleDriveService();
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

Cuando quiera cambiar con la implementación de Dropbox, debe reemplazar todas las líneas donde se new construye el objeto GoogleDriveService y usar el DropboxService. Además, al probar la clase SomeController, el constructor siempre espera que la clase GoogleDriveService y los métodos reales de esta clase se activen.

¿Cuándo es apropiado y cuándo no? En mi opinión, usted usa DI cuando cree que hay (o puede haber) implementaciones alternativas de una clase.


Entiendo que la respuesta ya se ha dado aquí. Pero sigo pensando que algunos conceptos básicos sobre la inversión de control deben discutirse aquí en detalle para futuros lectores.

Inversion of Control (IoC) se ha construido sobre un principio muy simple llamado Principio de Hollywood . Y dice eso,

No nos llames nosotros te llamamos

Lo que significa es que no vayas a Hollywood para cumplir tu sueño, sino que si eres digno, Hollywood te encontrará y hará que tu sueño se haga realidad. Bastante invertido, ¿eh?

Ahora, cuando discutimos sobre el principio de IoC, solemos olvidarnos de Hollywood. Para IoC, tiene que haber tres elementos, un Hollywood, usted y una tarea como cumplir su sueño.

En nuestro mundo de programación, Hollywood representa un marco genérico (puede ser escrito por usted o por otra persona), usted representa el código de usuario que escribió y la tarea representa lo que quiere lograr con su código. ¡Ahora nunca va a desencadenar su tarea por sí mismo, no en IoC! Más bien, ha diseñado todo de tal manera que su marco de trabajo activará su tarea para usted. Por lo tanto, has construido un marco reutilizable que puede convertir a alguien en un héroe u otro en un villano. Pero ese marco siempre está a cargo, sabe cuándo elegir a alguien y esa persona solo sabe lo que quiere ser.

Un ejemplo de la vida real sería dado aquí. Supongamos que quieres desarrollar una aplicación web. Por lo tanto, crea un marco que manejará todas las cosas comunes que una aplicación web debe manejar, como manejar la solicitud http, crear un menú de la aplicación, servir páginas, administrar cookies, desencadenar eventos, etc.

Y luego deja algunos enlaces en su marco donde puede colocar más códigos para generar un menú personalizado, páginas, cookies o registrar algunos eventos de usuario, etc. En cada solicitud del navegador, su marco se ejecutará y ejecutará sus códigos personalizados si se engancha y luego lo devuelve. al navegador.

Entonces, la idea es bastante simple. En lugar de crear una aplicación de usuario que controle todo, primero crea un marco reutilizable que controlará todo, luego escribirá sus códigos personalizados y los conectará al marco para ejecutarlos a tiempo.

Laravel y EJB son ejemplos de tales marcos.

Referencia:

https://martinfowler.com/bliki/InversionOfControl.html

https://en.wikipedia.org/wiki/Inversion_of_control


La creación de un objeto dentro de la clase se denomina acoplamiento apretado, Spring elimina esta dependencia siguiendo un patrón de diseño (DI / IOC). En qué objeto de clase se pasa en constructor en lugar de crear en clase. Además, damos una variable de referencia de super clase en el constructor para definir una estructura más general.


La inversión de control consiste en transferir el control de la biblioteca al cliente. Tiene más sentido cuando hablamos de un cliente que inyecta (pasa) un valor de función (expresión lambda) en una función de orden superior (función de biblioteca) que controla (cambia) el comportamiento de la función de biblioteca. Un cliente o marco que inyecta las dependencias de la biblioteca (que llevan el comportamiento) en las bibliotecas también puede considerarse IoC


Me gusta esta explicación: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

Comienza simple y muestra ejemplos de código también.

El consumidor, X, necesita la clase consumida, Y, para lograr algo. Todo eso es bueno y natural, pero ¿X realmente necesita saber que usa Y?

¿No es suficiente que X sepa que usa algo que tiene el comportamiento, los métodos, las propiedades, etc. de Y sin saber quién implementa realmente el comportamiento?

Al extraer una definición abstracta del comportamiento utilizado por X en Y, ilustrada como se muestra a continuación, y al permitirle al consumidor X usar una instancia de eso, en lugar de Y, puede seguir haciendo lo que hace sin tener que conocer los detalles específicos de Y.

En la ilustración de arriba, Y implementa I y X usa una instancia de I. Si bien es bastante posible que X aún use Y, lo interesante es que X no lo sabe. Solo sabe que usa algo que implementa yo.

Lea el artículo para obtener más información y una descripción de beneficios tales como:

  • X ya no depende de Y
  • Más flexible, la implementación se puede decidir en tiempo de ejecución
  • Aislamiento de la unidad de código, pruebas más fáciles.

...


Para comprender el concepto, la Inversión de control (IoC) o el Principio de inversión de dependencia (DIP) involucra dos actividades: abstracción e inversión. La inyección de dependencia (DI) es solo uno de los pocos métodos de inversión.

Para leer más sobre esto puedes leer mi blog Here

  1. ¿Qué es?

Es una práctica en la que permite que el comportamiento real provenga de fuera del límite (Clase en Programación Orientada a Objetos). La entidad límite solo conoce la abstracción (por ejemplo, interfaz, clase abstracta, delegado en Programación Orientada a Objetos) de la misma.

  1. ¿Qué problemas resuelve?

En términos de programación, IoC intenta resolver el código monolítico haciéndolo modular, desacoplando varias partes de él, y haciéndolo comprobable por unidad.

  1. ¿Cuándo es apropiado y cuándo no?

Es apropiado la mayoría del tiempo, a menos que tenga una situación en la que solo desee un código monolítico (por ejemplo, un programa muy simple)


Una explicación escrita muy simple se puede encontrar aquí.

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

Dice -

"Cualquier aplicación no trivial se compone de dos o más clases que colaboran entre sí para realizar alguna lógica de negocios. Tradicionalmente, cada objeto es responsable de obtener sus propias referencias a los objetos con los que colabora (sus dependencias). Al aplicar DI, el los objetos reciben sus dependencias en el momento de la creación por una entidad externa que coordina cada objeto en el sistema. En otras palabras, las dependencias se inyectan en los objetos ".


Usando IoC no estás renovando tus objetos. Su contenedor IoC hará eso y administrará la vida útil de ellos.

Resuelve el problema de tener que cambiar manualmente cada creación de instancias de un tipo de objeto a otro.

Es apropiado cuando tiene una funcionalidad que puede cambiar en el futuro o que puede ser diferente según el entorno o la configuración utilizada en.


Antes de usar Inversion of Control, debe tener muy en cuenta el hecho de que tiene sus pros y sus contras, y debe saber por qué lo usa si lo hace.

Pros:

  • Su código se desacopla para que pueda intercambiar fácilmente implementaciones de una interfaz con implementaciones alternativas
  • Es un motivador fuerte para codificar contra interfaces en lugar de implementaciones.
  • Es muy fácil escribir pruebas unitarias para su código porque no depende más que de los objetos que acepta en su constructor / configurador y puede inicializarlos fácilmente con los objetos correctos de forma aislada.

Contras:

  • IoC no solo invierte el flujo de control en su programa, sino que también lo nubla considerablemente. Esto significa que ya no puede leer su código y saltar de un lugar a otro porque las conexiones que normalmente estarían en su código ya no están en el código. En su lugar, se encuentra en los archivos de configuración XML o en las anotaciones y en el código de su contenedor IoC que interpreta estos metadatos.
  • Surge una nueva clase de errores en los que obtiene incorrectamente su configuración XML o sus anotaciones y puede pasar mucho tiempo descubriendo por qué su contenedor IoC inyecta una referencia nula en uno de sus objetos bajo ciertas condiciones.

Personalmente, veo los puntos fuertes de IoC y realmente me gustan, pero tiendo a evitar IoC siempre que sea posible porque convierte su software en una colección de clases que ya no constituyen un programa "real", sino simplemente algo que debe ser organizado por La configuración XML o los metadatos de anotación se caerían (y caerían) sin ellos.


Digamos que hacemos alguna reunión en algún hotel.

Mucha gente, muchas garrafas de agua, muchos vasos de plástico.

Cuando alguien quiere beber, ella llena la taza, la bebida y tira la taza al suelo.

Después de una hora o algo tenemos un piso cubierto de vasos de plástico y agua.

Vamos a invertir el control.

La misma reunión en el mismo lugar, pero en lugar de vasos de plástico tenemos un camarero con un vaso de vidrio (Singleton)

Y ella ofrece todo el tiempo a los huéspedes que beben.

Cuando alguien quiere beber, toma del vaso del camarero, bebe y devuélvelo al camarero.

Dejando a un lado la cuestión de la higiene, la última forma de control del proceso de bebida es mucho más efectiva y económica.

Y esto es exactamente lo que hace Spring (otro contenedor IoC, por ejemplo: Guice). En lugar de dejar que la aplicación cree lo que necesita usando una nueva palabra clave (tomar un vaso de plástico), el contenedor Spring IoC ofrece siempre la misma instancia (singleton) del objeto necesario (vaso de agua).

Piense en usted como organizador de dicha reunión. Necesita la forma de enviar un mensaje a la administración del hotel que

Los miembros de la reunión necesitarán un vaso de agua pero no un pedazo de pastel.

Ejemplo:-

public class MeetingMember {

    private GlassOfWater glassOfWater;

    ...

    public void setGlassOfWater(GlassOfWater glassOfWater){
        this.glassOfWater = glassOfWater;
    }
    //your glassOfWater object initialized and ready to use...
    //spring IoC  called setGlassOfWater method itself in order to
    //offer to meetingMember glassOfWater instance

}

Enlaces útiles:-


Inversion of Control, (o IoC), se trata de obtener la libertad (se casa, pierde la libertad y está siendo controlado. Se divorció, acaba de implementar la Inversión de control. Eso es lo que llamamos "desacoplamiento". Buen sistema informático desalienta una relación muy cercana.) más flexibilidad (la cocina de su oficina solo sirve agua limpia del grifo, esa es su única opción cuando quiere beber. Su jefe implementó Inversión de control al configurar una nueva máquina de café. Ahora obtiene la flexibilidad para elegir el agua del grifo o el café) y menos dependencia (su pareja tiene un trabajo, usted no tiene un trabajo, depende financieramente de su pareja, por lo que está controlado. Usted encuentra un trabajo, ha implementado la Inversión de Control. Un buen sistema informático fomenta la dependencia.)

Cuando usas una computadora de escritorio, tienes esclavos (o digamos, controlados). Tienes que sentarte ante una pantalla y mirarla. Usando el teclado para escribir y usando el mouse para navegar. Y un software mal escrito puede esclavizarte aún más. Si reemplazas tu escritorio con una computadora portátil, entonces inviertes un poco el control. Usted puede tomarlo fácilmente y moverse. Así que ahora puedes controlar dónde estás con tu computadora, en lugar de que tu computadora lo controle.

Al implementar la Inversión de control, un consumidor de software / objeto obtiene más controles / opciones sobre el software / objetos, en lugar de ser controlado o tener menos opciones.

Con las ideas anteriores en mente. Todavía nos falta una parte clave de la IoC. En el escenario de IoC, el consumidor de software / objeto es un marco sofisticado. Eso significa que el código que creaste no es llamado por ti mismo. Ahora vamos a explicar por qué esta forma funciona mejor para una aplicación web.

Supongamos que su código es un grupo de trabajadores. Necesitan construir un coche. Estos trabajadores necesitan un lugar y herramientas (un marco de software) para construir el automóvil. Un marco de software tradicional será como un garaje con muchas herramientas. Así que los trabajadores necesitan hacer un plan ellos mismos y usar las herramientas para construir el auto. Construir un auto no es un negocio fácil, será muy difícil para los trabajadores planificar y cooperar adecuadamente. Un marco de software moderno será como una fábrica de automóviles moderna con todas las instalaciones y los administradores en su lugar. Los trabajadores no tienen que hacer ningún plan, los gerentes (parte del marco, son las personas más inteligentes y el plan más sofisticado) ayudarán a coordinar para que los trabajadores sepan cuándo hacer su trabajo (el marco llama a su código). Los trabajadores solo tienen que ser lo suficientemente flexibles para usar cualquier herramienta que los gerentes les proporcionen (mediante el uso de inyección de dependencia).

Aunque los trabajadores otorgan el control de la gestión del proyecto en el nivel superior a los gerentes (el marco). Pero es bueno tener algunos profesionales que ayuden. Este es el concepto de IoC que realmente proviene.

Las aplicaciones web modernas con una arquitectura MVC dependen del marco para realizar el enrutamiento de URL y poner controladores en su lugar para que el marco llame.

La inyección de dependencia y la inversión de control están relacionadas. La inyección de dependencia se encuentra en el nivel micro y la inversión de control en el nivel macro . Tienes que comer cada bocado (implementa DI) para terminar una comida (implementa IoC).


IoC / DI para mí es eliminar las dependencias de los objetos que llaman. Super simple

La respuesta no técnica es poder cambiar un motor en un automóvil justo antes de encenderlo. Si todo se engancha bien (la interfaz), eres bueno.


La inversión de los controles se trata de separar las preocupaciones.

Sin IoC : tienes una computadora portátil y rompes accidentalmente la pantalla. Y, maldición, usted encuentra que el mismo modelo de pantalla de computadora portátil no se encuentra en ninguna parte del mercado. Así que estás atascado.

Con IoC : tienes una computadora de escritorio y rompes accidentalmente la pantalla. Usted encuentra que simplemente puede tomar casi cualquier monitor de escritorio del mercado, y funciona bien con su escritorio.

Su escritorio implementa exitosamente IoC en este caso. Acepta una variedad de monitores, mientras que la computadora portátil no, necesita una pantalla específica para arreglarse.


Los patrones de inversión de control (IoC) y de inyección de dependencia (DI) tratan de eliminar las dependencias de su código.

Por ejemplo, digamos que su aplicación tiene un componente de editor de texto y que desea proporcionar una revisión ortográfica. Su código estándar se vería así:

public class TextEditor {

    private SpellChecker checker;

    public TextEditor() {
        this.checker = new SpellChecker();
    }
}

Lo que hemos hecho aquí crea una dependencia entre TextEditor y SpellChecker . En un escenario de IoC, haríamos algo como esto:

public class TextEditor {

    private IocSpellChecker checker;

    public TextEditor(IocSpellChecker checker) {
        this.checker = checker;
    }
}

En el primer ejemplo de código, estamos creando una instancia de this.checker = new SpellChecker(); ( this.checker = new SpellChecker(); ), lo que significa que la clase TextEditor depende directamente de la clase de SpellChecker .

En el segundo ejemplo de código, estamos creando una abstracción teniendo la clase de dependencia SpellChecker en la firma del constructor TextEditor (no inicializando la dependencia en la clase). Esto nos permite llamar a la dependencia y luego pasarla a la clase TextEditor así:

SpellChecker sc = new SpellChecker; // dependency
TextEditor textEditor = new TextEditor(sc);

Ahora el cliente que crea la clase TextEditor tiene el control sobre qué implementación de SpellChecker usar porque estamos inyectando la dependencia a la firma TextEditor .

Este es solo un ejemplo simple, hay una buena serie de artículos de Simone Busoli que lo explican con mayor detalle.


Pero creo que hay que tener mucho cuidado con ello. Si usará demasiado este patrón, creará un diseño muy complicado e incluso un código más complicado.

Como en este ejemplo con TextEditor: si solo tienes un SpellChecker, ¿quizás no es realmente necesario usar IoC? A menos que necesites escribir pruebas unitarias o algo ...

De todos modos: ser razonable. Los patrones de diseño son buenas prácticas pero no la Biblia para predicar. No lo pegues en todas partes.


Por ejemplo, la tarea # 1 es crear un objeto. Sin el concepto IOC, la tarea # 1 debe ser realizada por Programmer. Pero con el concepto IOC, la tarea # 1 se debe realizar por contenedor.

En resumen, el control se invierte del programador al contenedor. Por eso, se llama inversión de control.

He encontrado un buen ejemplo here .


Supongamos que eres un objeto. Y vas a un restaurante:

Sin IoC : pides "manzana" y siempre te sirven manzana cuando pides más.

Con IoC : puedes pedir "fruta". Puedes obtener diferentes frutas cada vez que te sirven. por ejemplo, manzana, naranja o melón de agua.

Entonces, obviamente, se prefiere IoC cuando te gustan las variedades.


Escribiré mi comprensión simple de estos dos términos:

For quick understanding just read examples*

Inyección de dependencia (DI):
La inyección de dependencia generalmente significa pasar un objeto del cual el método depende, como parámetro de un método, en lugar de que el método cree el objeto dependiente .
Lo que significa en la práctica es que el método no depende directamente de una implementación particular; Cualquier implementación que cumpla con los requisitos se puede pasar como parámetro.

Con esto los objetos cuentan sus dependencias. Y la primavera lo pone a disposición.
Esto lleva al desarrollo de aplicaciones acopladas libremente.

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

Contenedor de Inversión de Control (IoC):
Esta es una característica común de los marcos, IOC gestiona objetos java.
- Desde la instanciación hasta la destrucción a través de su BeanFactory.
-Los componentes Java creados por el contenedor IoC se denominan beans, y el contenedor IoC administra el alcance de un bean, los eventos del ciclo de vida y cualquier característica de AOP para la cual se ha configurado y codificado.

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it .

Al implementar la Inversión de control, un consumidor de software / objeto obtiene más controles / opciones sobre el software / objetos, en lugar de ser controlado o tener menos opciones.

La inversión de control como una guía de diseño sirve para los siguientes propósitos:

Hay un desacoplamiento de la ejecución de una determinada tarea de la implementación.
Cada módulo puede centrarse en aquello para lo que está diseñado.
Los módulos no hacen suposiciones sobre lo que hacen otros sistemas, sino que dependen de sus contratos.
Reemplazar módulos no tiene ningún efecto secundario en otros módulos
Mantendré las cosas abstractas aquí. Puede visitar los siguientes enlaces para conocer en detalle el tema.
Una buena lectura con ejemplo.

Explicación detallada







inversion-of-control