qué ioc inyeccion inversión injection informatica explicacion dependency dependencias control c++ dependency-injection inversion-of-control

ioc - ¿Cuál es la diferencia entre la inversión de control y la inyección de dependencia en C++?



ioc informatica (2)

He estado leyendo recientemente sobre DI y IoC en C ++. Estoy un poco confundido (incluso después de leer preguntas relacionadas aquí en SO) y esperaba alguna aclaración.

Me parece que estar familiarizado con el STL y Boost conduce al uso de la inyección de dependencia bastante. Por ejemplo, digamos que hice una función que encontró la media de un rango de números:

template <typename Iter> double mean(Iter first, Iter last) { double sum = 0; size_t number = 0; while (first != last) { sum += *(first++); ++number; } return sum/number; };

¿Esto (es decir, usar iteradores en lugar de acceder a la colección en sí) inyección de dependencia? ¿Inversión de control? ¿Ninguno?

Veamos otro ejemplo. Tenemos una clase:

class Dice { public: typedef boost::mt19937 Engine; Dice(int num_dice, Engine& rng) : n_(num_dice), eng_(rng) {} int roll() { int sum = 0; for (int i = 0; i < num_dice; ++i) sum += boost::uniform_int<>(1,6)(eng_); return sum; } private: Engine& eng_; int n_; };

Esto parece una inyección de dependencia. Pero, ¿es inversión de control?

Además, si me falta algo, ¿alguien puede ayudarme? Esta parece ser la forma natural de hacer las cosas, así que si eso es todo lo que hay para Dependency Injection, ¿por qué las personas tienen dificultades para usarlo?


Déjame intentar responder.

Tu primer ejemplo es ninguno de los dos. Es simplemente una plantilla.

Para que sea una inyección de dependencia, se debería haber elegido una IMPLEMENTACIÓN y se debe proporcionar a la plantilla.

Para que sea IoC, la plantilla debería proporcionarse en tiempo de ejecución (no en tiempo de compilación) al tipo IMPLEMENTACIÓN, y usarse como la implementación de la función "mean ()" (piense en una fábrica que proporcione implementaciones de funciones medias)

Su segundo ejemplo parece un consumidor de DI / IoC. El código que envía la implementación de Engine a su clase sería el componente DI / IoC.

Con suerte, eso es preciso y ayuda.


Inversion of Control es un concepto muy genérico, con diferentes significados dependiendo del tipo de "control" del que está hablando. La inyección de dependencia es una forma específica.

Inversión de control e iteración

En este caso, "control" significa "control de flujo".

Creo que su primer ejemplo que involucra iteración no es realmente inversión de control, porque ese código hace explícitamente el control de flujo. La inversión del control separaría la acción a realizar del control de flujo. Puede verse así (perdón por mi java / C #):

SumVisitor sumVisitor = new SumVisitor(); collection.AcceptVisitor(sumVisitor); int sum = sumVisitor.GetSum();

El objeto visitante hace algo por cada elemento de colección que visita, por ejemplo, actualizar un campo de contador de suma. Pero no tiene control sobre cómo o cuándo es convocado por la colección, por lo tanto, inversión del control . También podría implementar MedianVisitor , MeanVisitor , MaximumVisitor , etcétera. Cada uno implementa una interfaz de IVisitor genérica con un método de Visit(Element) .

Para la colección, sucede todo lo contrario: no tiene conocimiento de lo que hace el visitante y simplemente se ocupa del control de flujo llamando al visitor.Visit(element) para cada elemento de la colección. Las diferentes implementaciones de visitantes tienen el mismo aspecto para la colección.

Inversión del control y construcción del gráfico del objeto

En este caso, "control" significa "control sobre cómo se crean y cablean los componentes".

En cualquier aplicación no trivial, el código se divide en componentes que tienen que colaborar. Para mantener los componentes reutilizables, no se pueden crear directamente entre sí ya que los unirían permanentemente. En cambio, los componentes individuales renuncian al control sobre la construcción y el cableado de los componentes.

La inyección de dependencias es una forma de lograr esto, tomando referencias a objetos colaboradores en el constructor. Luego necesita una pieza separada de código de inicio donde todos los componentes se crean y conectan entre sí, o un marco de inyección de dependencia que se ocupa de esto por usted. Su clase de dados es de hecho un ejemplo de inyección de dependencia.

Otra forma de ceder el control sobre la construcción de gráficos de objetos es el patrón del Localizador de Servicios , aunque tiene sus desventajas .