266 votos

Inyección de Dependencias vs Patrón de Fábrica

La mayoría de los ejemplos citados para el uso de la Inyección de Dependencias, también los podemos resolver utilizando el patrón factory. Parece que cuando se trata de uso/diseño la diferencia entre la inyección de dependencia y el factory es difusa o delgada.

¡Una vez alguien me dijo que es la forma en que lo utilizas lo que marca la diferencia!

Una vez utilicé StructureMap un contenedor de DI para resolver un problema, más tarde lo rediseñé para funcionar con un factory simple y eliminé las referencias a StructureMap.

¿Alguien puede decirme cuál es la diferencia entre ellos y dónde se debe usar qué, cuál es la mejor práctica aquí?

176voto

willcodejavaforfood Puntos 20365

Cuando usas una fábrica, tu código todavía es responsable de crear objetos. Con la inyección de dependencias, externalizas esa responsabilidad a otra clase o un framework, que está separado de tu código.

132voto

Perpetualcoder Puntos 7381

Yo sugeriría mantener los conceptos simples y claros. La Inyección de Dependencias es más bien un patrón arquitectónico para desacoplar de forma flexible los componentes de software. El patrón de fábrica es simplemente una forma de separar la responsabilidad de crear objetos de otras clases hacia otra entidad. El patrón de fábrica puede ser llamado una herramienta para implementar la Inyección de Dependencias. La inyección de dependencias puede ser implementada de muchas formas, como DI utilizando constructores, usando archivos de mapeo XML, etc.

65voto

Despertar Puntos 5365

Inyección de dependencias

En lugar de instanciar las partes por sí mismo, un coche pide las partes que necesita para funcionar.

class Car
{
    private Engine engine;
    private SteeringWheel wheel;
    private Tires tires;

    public Car(Engine engine, SteeringWheel wheel, Tires tires)
    {
        this.engine = engine;
        this.wheel = wheel;
        this.tires = tires;
    }
}

Factoría

Une las piezas para hacer un objeto completo y oculta el tipo concreto al llamador.

static class CarFactory
{
    public ICar BuildCar()
    {
        Engine engine = new Engine();
        SteeringWheel steeringWheel = new SteeringWheel();
        Tires tires = new Tires();
        ICar car = new RaceCar(engine, steeringWheel, tires);
        return car;
    }   
}

Resultado

Como puedes ver, las factorías y la inyección de dependencias se complementan entre sí.

static void Main()
{
     ICar car = CarFactory.BuildCar();
     // usa el coche
}

¿Recuerdas a Ricitos de Oro y los tres osos? Bueno, la inyección de dependencias es algo así. Aquí hay tres formas de hacer lo mismo.

void RaceCar() // ejemplo #1
{
    ICar car = CarFactory.BuildCar();
    car.Race();
}

void RaceCar(ICarFactory carFactory) // ejemplo #2
{
    ICar car = carFactory.BuildCar();
    car.Race();
}

void RaceCar(ICar car) // ejemplo #3
{
    car.Race();
}

Ejemplo #1 - Este es el peor porque oculta completamente la dependencia. Si miraras el método como una caja negra no tendrías idea de que requería un coche.

Ejemplo #2 - Esto es un poco mejor porque ahora sabemos que necesitamos un coche ya que pasamos una factoría de coches. Pero esta vez estamos pasando demasiado ya que todo lo que realmente necesita el método es un coche. Estamos pasando una factoría solo para construir el coche cuando el coche podría ser construido fuera del método y pasado.

Ejemplo #3 - Esto es ideal porque el método pide exactamente lo que necesita. Ni más ni menos. No tengo que escribir un MockCarFactory solo para crear MockCars, puedo pasar el mock directamente. Es directo y la interfaz no miente.

Esta charla técnica de Google por Misko Hevery es increíble y es la base de la que derivé mi ejemplo. http://www.youtube.com/watch?v=XcT4yYu_TTs

32voto

yfeldblum Puntos 42613

Hay problemas que son fáciles de resolver con inyección de dependencias y que no se resuelven tan fácilmente con un conjunto de fábricas.

Algunas de las diferencias entre, por un lado, inversión de control e inyección de dependencias (IOC/DI), y por otro lado, un localizador de servicios o un conjunto de fábricas (fábrica), son:

IOC/DI es un ecosistema completo de objetos de dominio y servicios en sí mismo. Configura todo para ti de la manera que especificas. Tus objetos de dominio y servicios son construidos por el contenedor, y no se construyen a sí mismos: por lo tanto, no tienen ninguna dependencia en el contenedor o en ninguna fábrica. IOC/DI permite un grado extremadamente alto de configurabilidad, con toda la configuración en un solo lugar (construcción del contenedor) en la capa superior de tu aplicación (la GUI, el frente web).

La fábrica abstrae parte de la construcción de tus objetos de dominio y servicios. Pero los objetos de dominio y servicios siguen siendo responsables de averiguar cómo construirse a sí mismos y cómo obtener todas las cosas en las que dependen. Todas estas dependencias "activas" se filtran a través de todas las capas de tu aplicación. No hay un solo lugar al que acudir para configurar todo.

16voto

Pup Puntos 3505

La gestión del ciclo de vida es una de las responsabilidades que los contenedores de dependencias asumen además de la instanciación e inyección. El hecho de que a veces el contenedor mantenga una referencia a los componentes después de la instanciación es la razón por la que se llama "contenedor" y no fábrica. Los contenedores de inyección de dependencias generalmente solo mantienen una referencia a los objetos que necesita gestionar para el ciclo de vida, o que se reutilizan para futuras inyecciones, como singletons o flyweights. Cuando se configura para crear nuevas instancias de algunos componentes para cada llamada al contenedor, el contenedor generalmente solo olvida el objeto creado.

De: http://tutorials.jenkov.com/dependency-injection/dependency-injection-containers.html

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X