¿La inyección de dependencia a mano es una mejor alternativa a la composición y al polimorfismo?

13

Primero, soy un programador de nivel de entrada; De hecho, estoy terminando un título de AS con un proyecto final final durante el verano. En mi nuevo trabajo, cuando no hay algún proyecto para mí (están esperando llenar el equipo con más nuevas contrataciones), me han dado libros para leer y aprender mientras espero: algunos libros de texto, otros no tanto (como Code Complete). Después de leer estos libros, recurrí a Internet para aprender lo más posible y comencé a aprender sobre SOLID y DI (hablamos sobre el principio de sustitución de Liskov, pero no sobre muchas otras ideas SOLID). Entonces, como he aprendido, me senté para aprender mejor y comencé a escribir algo de código para utilizar DI a mano (no hay marcos de DI en las computadoras de desarrollo).

La cosa es que, mientras lo hago, me doy cuenta de que me resulta familiar ... y parece que se parece mucho al trabajo que he hecho en el pasado usando la composición de clases abstractas usando polimorfismo. ¿Me estoy perdiendo una imagen más grande aquí? ¿Hay algo sobre DI (al menos a mano) que vaya más allá de eso? Entiendo la posibilidad de tener configuraciones que no están en el código de algunos marcos DI que tienen grandes beneficios en cuanto a cambiar las cosas sin tener que volver a compilar, pero cuando lo hago a mano, no estoy seguro de si es diferente de lo mencionado anteriormente ... ¡Una idea de esto sería muy útil!

Drake Clarris
fuente

Respuestas:

21

La idea fundamental en DI es simplemente insertar dependencias en los objetos, en lugar de permitirles extraer dependencias del exterior. Esto también se llamó "inversión de control" anteriormente. Esto le permite a uno controlar mejor las dependencias y, por último, pero no menos importante, escribir código que sea fácil de probar.

Los marcos DI solo se basan en esta idea, y (en parte) automatizan la parte a menudo tediosa del cableado de dependencias de objetos. De lo contrario, esto puede requerir una cantidad significativa de código en un proyecto más grande cuando se hace a mano.

Para definir dependencias, además de los archivos de configuración externos, también es posible usar anotaciones de código en la actualidad, por ejemplo, en lenguajes como Java y C #. Estos pueden traer lo mejor de ambos mundos: dependencias de cableado en un estilo declarativo, pero justo dentro del código, donde pertenece lógicamente. Para mí, la posibilidad de cambiar las dependencias sin tener que volver a compilar no es tan valiosa, ya que rara vez se hace en la vida real (aparte de algunos casos especiales), pero introduce una separación a menudo artificial de las dependencias de las clases y los objetos definidos en el código .

Para volver a la pregunta del título, DI no es una alternativa a la composición ni al polimorfismo; después de todo, esto es posible gracias a estos dos.

Péter Török
fuente
1
La inyección de dependencia (DI) es una forma de inversión de control (IoC).
Matthew Flynn
@MatthewFlynn, de hecho. Para referencia: martinfowler.com/articles/injection.html
Péter Török
1
Esa es mi referencia. Habla sobre los nuevos "contenedores livianos" que invierten el control, algo que ya era común ya que los oyentes de eventos de IU eran una forma de IoC. Dobla el enlace de objeto que Spring y otros contenedores de IoC hacen como Inyección de dependencia para diferenciarlo de la otra forma de Inversión de control.
Matthew Flynn
Vaya, me perdí el "hecho". Pensé que me estabas contradiciendo ... Lo siento.
Matthew Flynn
Tu último párrafo me hace sentir un poco mejor; Todo el tiempo que estuve trabajando en mi pequeño proyecto de aprendizaje, me decía a mí mismo, "esto se siente como polimorfismo ...". Desafortunadamente, .Net y c # en mi trabajo están terriblemente desactualizados, pero al analizarlo, ¿es Unity el marco de trabajo integrado de c # del que estás hablando?
Drake Clarris
22

El mejor artículo que he leído sobre el tema fue el de James Shore . He estado haciendo " DI a mano " durante años, como parte de la abstracción y el polimorfismo. Entonces, después de ingresar al mundo profesional y seguir escuchando ese término, tuve una gran desconexión entre lo que pensé que debería significar la palabra y lo que realmente significa:

La "inyección de dependencia" es un término de 25 dólares para un concepto de 5 centavos.

Eso es de la publicación de Shore, que me aclaró todo. Por ejemplo:

Dado

class Engine {public abstract void start()}
class V8 extends Engine {...}
class V6 extends Engine {...}

En lugar de escribir:

class Car
{
    private Engine engine;
    public Car()
    {
        this.engine = new V6();
    }

    public void start()
    {
        this.engine.start();
    }
}

Tu escribes algo como esto:

class Car
{
    private Engine engine;
    public Car(Engine a)
    {
        this.engine = a;
    }

    public void start()
    {
        this.engine.start();
    }
}

...

Car F = new Car(new V8());

Y esto evita que la Carinstancia tenga que manejar Enginedetalles específicos . Un automóvil solo necesita un motor, no le importa cuál, siempre y cuando implemente la funcionalidad básica del motor. Es decir, su Carclase no está vinculada a una dependencia de implementación específica; se "inyecta" en otra parte, potencialmente en tiempo de ejecución.

Este ejemplo específico de Car utiliza el subtipo de DI denominado "Inyección del constructor", lo que significa que la dependencia se transfirió como argumento del constructor. También puede usar un setEngine(Engine a)método para "Inyección de Setter", etc., pero estos subtipos me parecen pedantes.

Sin embargo, un poco más lejos, muchos marcos DI proporcionan la base para conectar un grupo de estas cosas más abstractamente referenciadas entre sí.

Eso es.

Mella
fuente
0

No soy un experto, ya que solo comencé a usar DI en los últimos años, pero algunos de los temas / funcionalidades útiles de los contenedores DI que he notado son (que no considero como productos de composición / polimorfismo (pero puedo soportar ser corregido en eso):

  • eje central de creación de objetos
  • proporcionar singletons por hilo
  • técnicas orientadas a aspectos como la intercepción
Aaron Anodide
fuente
0

Además de DI, hay una configuración de composición de clase en la aplicación raíz (en lugar de configurar usando xml). No hay necesidad de ningún marco DI o IoC, a pesar de que pueden ordenar la configuración de composición de clase, particularmente para proyectos grandes. Esto se debe a que el marco DI normalmente viene con un contenedor que implementa características adicionales, como el cableado automático, que ayuda a configurar la composición de la clase. Puede leer mi entrada de blog para extraer mi comprensión sobre este tema.

kusnaditjung tjung
fuente