tipos que patron para inyección inyeccion injection dummies dependency dependencias dependencia control c++ unit-testing dependency-injection

que - Inyección de dependencia en C++



que es la inyección de dependencia (8)

En C ++, normalmente, cuando hace las cosas bien, no necesita escribir destructores en la mayoría de los casos. Debe usar punteros inteligentes para eliminar cosas automáticamente. Creo que el constructor no se parece al propietario de las instancias ClassA y ClassB. Si no le gusta usar punteros inteligentes, debe pensar en los objetos de por vida y sus propietarios.

Esta es también una pregunta que hice en un comentario en una de las charlas de google de Miško Hevery que trataba sobre la inyección de dependencia, pero fue enterrado en los comentarios.

Me pregunto cómo puede el paso de fábrica / constructor de conectar las dependencias en conjunto puede funcionar en C ++.

Es decir, tenemos una clase A que depende de B. El constructor asignará B en el montón, pasará un puntero a B en el constructor de A mientras también asignará en el montón y devolverá un puntero a A.

¿Quién limpia después? ¿Es bueno dejar que el constructor limpie después de que esté hecho? Parece ser el método correcto, ya que en la charla dice que el constructor debe configurar objetos que se espera que tengan la misma duración o al menos las dependencias tengan una mayor duración (también tengo una pregunta sobre eso). Lo que quiero decir en código:

class builder { public: builder() : m_ClassA(NULL),m_ClassB(NULL) { } ~builder() { if (m_ClassB) { delete m_ClassB; } if (m_ClassA) { delete m_ClassA; } } ClassA *build() { m_ClassB = new class B; m_ClassA = new class A(m_ClassB); return m_ClassA; } };

Ahora bien, si hay una dependencia que se espera que dure más tiempo que la duración del objeto en el que lo estamos inyectando (digamos que ClassC es esa dependencia), entiendo que deberíamos cambiar el método de compilación a algo así como:

ClassA *builder::build(ClassC *classC) { m_ClassB = new class B; m_ClassA = new class A(m_ClassB, classC); return m_ClassA; }

¿Cuál es tu enfoque preferido?


Usa RAII.

Darle un puntero sin procesar a alguien es lo mismo que darles la propiedad. Si eso no es lo que quieres hacer, deberías darle algún tipo de fachada que también sepa cómo limpiar el objeto en cuestión.

shared_ptr <> puede hacer esto; el segundo argumento de su constructor puede ser un objeto de función que sepa cómo eliminar el objeto.


Las cosas se complican si no resuelves la cuestión de la propiedad de una vez por todas. Simplemente tendrá que decidir en su implementación si es posible que las dependencias vivan más que los objetos en los que se inyectan.

Personalmente, diría que no: el objeto al que se inyecta la dependencia se eliminará después. Tratar de hacerlo a través del generador significa que el constructor tendrá que vivir más tiempo que la dependencia y el objeto en el que se inyecta. Esto causa más problemas de los que soluciona, en mi opinión, porque el constructor no sirve para ningún propósito más útil después de que se haya completado la construcción con la inyección de dependencia.


Esto es interesante, DI en C ++ usando plantillas:

http://adam.younglogic.com/?p=146

Creo que el autor está haciendo los movimientos correctos para no traducir Java DI en C ++ demasiado literalmente. Vale la pena leer.


Según mi propia experiencia, es mejor tener reglas claras de propiedad. Para objetos concretos pequeños, es mejor usar copia directa para evitar la dependencia cruzada.

En ocasiones, la dependencia cruzada es inevitable y no existe una propiedad clara. Por ejemplo, instancias de (m) A instancias propias (n) B, y ciertas instancias B pueden ser propiedad de múltiples As. En este caso, el mejor enfoque es aplicar el recuento de referencias a B, de forma similar al recuento de referencias COM. Cualquier función que tome posesión de B * debe aumentar el conteo de referencia primero, y disminuirla cuando libera la posesión.

También evito usar boost :: shared_ptr ya que crea un nuevo tipo (shared_ptr y B * se convierten en dos tipos distintos). Descubrí que trae más dolores de cabeza cuando agrego métodos.


Recientemente he sido mordido por el error DI. Creo que resuelve muchos problemas de complejidad, especialmente la parte automatizada. He escrito un prototipo que te permite usar DI de una manera bastante C ++, o al menos eso creo. Puede echar un vistazo al ejemplo de código aquí: http://codepad.org/GpOujZ79

Las cosas que obviamente están ausentes: sin alcance, sin enlace de la interfaz a la implementación. Este último es bastante fácil de resolver, el primero, no tengo ni idea.

Estaría agradecido si alguien aquí tiene una opinión sobre el código.


También puede verificar la inyección de dependencia de FFEAD . Proporciona DI en las líneas de Spring for JAVA y tiene una forma no molesta de manejar las cosas. También tiene muchas otras funciones importantes, como soporte integrado AJAX, reflexión, serialización, intérprete C ++, componentes empresariales para C ++, ORM, mensajería, servicios web, grupos de subprocesos y un servidor de aplicaciones que admite todas estas características.


Esta charla es sobre Java e inyección de dependencia.

En C ++ tratamos de NO pasar punteros RAW. Esto se debe a que un puntero RAW no tiene semántica de propiedad asociada. Si no tiene propiedad, entonces no sabemos quién es el responsable de limpiar el objeto.

Encuentro que la mayoría de las veces la inyección de dependencia se realiza mediante referencias en C ++.
En los casos poco comunes en los que debe usar punteros, envuélvalos en std :: unique_ptr <> o std :: shared_ptr <> según cómo desee administrar la propiedad.
En caso de que no pueda usar las características de C ++ 11, use std :: auto_ptr <> o boost :: shared_ptr <>.

También me gustaría señalar que los estilos de programación en C ++ y Java son ahora tan divergentes que aplicar el estilo de un idioma al otro inevitablemente conducirá al desastre.