Pregunta

Nota:Las preguntas están al final del post.

He leído los otros hilos de stackoverflow sobre Método de fábrica abstracta versus método de fábrica.Entiendo la intención de cada patrón.Sin embargo, no tengo clara la definición.

El método de fábrica define una interfaz para crear un objeto, pero permite que las subclases decidan cuál de ellos instanciar.Un método de fábrica permite a las clases diferir la instancia a las subclases.

Por el contrario, una fábrica abstracta proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas.

-John Feminella

El Fábrica abstracta se parece mucho a la Método de fábrica.He dibujado algunas clases de UML para ilustrar mi punto.

Nota:

  • El diagrama es de www.yuml.com por lo que no están perfectamente orientados.Pero es un servicio gratuito :).
  • Es posible que los diagramas no sean perfectos.todavía estoy aprendiendo el GoF patrones de diseño.

Método de fábrica:

Factory Method

Abstract Factory (solo 1 miembro):

Abstract Factory (only 1 member)

Abstract Factory (más miembros):

alt text

Preguntas:

  1. Si el Fábrica abstracta tiene un solo creador y un producto, ¿sigue siendo el Fábrica abstracta ¿patrón? (una interfaz para crear familias)
  2. Puede el Método de fábrica ¿El creador concreto debe crearse desde una interfaz o tiene que ser desde una clase? (las clases difieren las instancias a subclases)
  3. Si la Abstract Factory puede tener sólo un creador y un producto, ¿es la única diferencia entre la Fábrica abstracta y el Método de fábrica ¿Que el creador de la primera es una Interfaz y el creador de la segunda es una Clase?
¿Fue útil?

Solución

Espero que esto ayude.Describe los distintos tipos de fábricas.solía Primero los patrones de diseño como mi referencia.solía yuml.me para diagramar.

Fábrica estática

Es una clase con un método estático para producir varios subtipos de Producto.

Static Factory

Fábrica sencilla

Es una clase que puede producir varios subtipos de Producto.(Es mejor que Static Factory.Cuando se agregan nuevos tipos, no es necesario cambiar la clase de producto base, solo la clase de fábrica simple).

Simple Factoryt

Método de fábrica

Contiene un método para producir un tipo de producto relacionado con su tipo.(Es mejor que una fábrica simple porque el tipo se difiere a una subclase).

Factory Method

Fábrica abstracta

Produce una familia de tipos que están relacionados.Es notablemente diferente de un método de fábrica ya que tiene más de un método de tipos que produce.(Esto es complicado; consulte el siguiente diagrama para ver un mejor ejemplo de la vida real).

Abstract Factory

Ejemplo del marco .NET

DbFactoriesProvider es una fábrica simple ya que no tiene subtipos.DbFactoryProvider es una fábrica abstracta, ya que puede crear varios objetos de base de datos relacionados, como objetos de conexión y comando.

Abstract Factory From .NET Framework ​​​

Otros consejos

Los dos patrones son sin duda relacionado!

La diferencia entre los patrones está generalmente en la intención.

La intención Método de fábrica es "Definir una interfaz para crear un objeto, sino dejar que las subclases decidir qué clase instanciar. Método de fábrica permite una diferir de instancias de clase a las subclases . "

La intención de Abstract Factory es "Proporcionar una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas."

basado puramente en estas declaraciones de intención (citado de GoF), diría que, efectivamente, Método de fábrica es, en cierto sentido un "degenerado" Abstract Factory con una familia de uno.

Por lo general, tienden a diferir en la implementación, como Método de fábrica es un buen negocio más simple que Abstract Factory .

Se relacionan también en la ejecución, sin embargo. Como se señaló en el libro GoF,

  

AbstractFactory sólo declara una interfaz para la creación de productos. Todo depende de ConcreteProduct subclases para crear realmente ellos. La forma más común de hacer esto es definir un método de fábrica para cada producto.

c2 wiki también tiene algo interesante discusión sobre este tema.

Parece que la lista de la OP (excelente) de las preguntas ha sido ignorado. respuestas actuales se limitan a ofrecer definiciones refrito. Así que voy a tratar de hacer frente a las preguntas originales de forma concisa.

  
      
  1. Si el Abstract Factory tiene sólo un creador y un producto, ¿sigue siendo el Abstract Factory patrón? (Una interfaz para   crear Familes)
  2.   

No . Una fábrica abstracta debe crear más de un producto para hacer una "familia de productos". El ejemplo GoF canónica crea ScrollBar() y Window(). La ventaja (y propósito) es que el extracto de fábrica puede hacer cumplir un tema común a través de sus múltiples productos.

  
      
  1. ¿Puede el Método de fábrica creador concreto se creó a partir de una interfaz o tiene que ser de una clase? (Clases Defer   instanciaciones a subclases)
  2.   

En primer lugar, hay que señalar que ni Java o C # existían cuando el GoF escribió su libro. El uso del término GoF Interfaz no está relacionado con los tipos de interfaz introducidas por las lenguas particulares. Por lo tanto, el creador concreto puede ser creado a partir de cualquier API. El punto importante en el patrón es que la API consume su propio método de fábrica, por lo que una interfaz con un solo método no puede ser un método de fábrica más de lo que puede ser una fábrica abstracta.

  
      
  1. Si el resumen de fábrica sólo puede tener un creador y un producto, es la única diferencia entre el Abstract Factory y la    Método de fábrica que el creador de la primera es una interfaz y el creador de este último es una clase?
  2.   

Esta pregunta ya no es válida, a raíz de las respuestas anteriores; Sin embargo, si usted está pensando izquierda que la única diferencia entre Abstract Factory y método de fábrica es el número de productos creada, tenga en cuenta cómo un cliente consume cada uno de estos patrones. Un resumen de fábrica normalmente se inyecta en su cliente y se invoca a través de composición / delegación. Un método de fábrica debe ser heredado. Así que todo vuelve a la vieja discusión herencia composición vs.

Sin embargo, estas respuestas han planteado una cuarta pregunta!

  
      
  1. Desde una interfaz con un solo método no puede ser un Método de fábrica más de lo que puede ser un Abstract Factory ¿Qué hacemos una llamada   creacional interfaz con un solo método?
  2.   

Si el método es estático, que comúnmente se llama un estático fábrica . Si el método no es estática, se llama comúnmente un simple de la fábrica . Ninguno de estos es un patrón GoF, pero en la práctica son mucho más comúnmente utilizados!

En mi opinión, la ligera diferencia entre los dos patrones reside en el aplicación , y así, como ya se ha dicho, en el Intención .

resumen Vamos a las definiciones (ambos de Wikipedia).

Abstract Factory

  

proporcionar una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas.

Método de fábrica

  

Definir un interfaz para crear un objeto , pero dejar que las clases que implementan la interfaz de decidir qué clase instanciar . El método permite una fábrica de instancias de la clase a aplazar subclases.

Ambos patrones permiten desacoplar los objetos de usuario de creación de instancias necesarios (en tiempo de ejecución de desacoplamiento), y este es el aspecto común. Ambos patrones permiten crear una jerarquía de fábricas de acuerdo con las necesidades específicas, y esto es otro aspecto común.

Abstract Factory permite crear varios tipos diferentes de instancias en una sub-clase, y para particularizar el comportamiento creaciones en sus diferentes sub-clases; Normalmente, el método de fábrica declara la creación de un solo tipo de objeto que puede ser particularizado de acuerdo con el mecanismo de subclasificar. Esa es la diferencia.

Al resumir. Digamos que el Producto define la super-clase de los objetos que crean, y que producta y ProductB son dos diferentes subclases. Por lo tanto, el método Abstract Factory tendrá dos métodos, createProductA () y createProductB (), que se particulariza (en términos de pasos de creación) en sus específicos subclases: la fábrica subclases particularizan el pasos de creación para las dos clases de objetos definidos en virtud de la creación.

De acuerdo con el ejemplo anterior, el método de fábrica se llevará a cabo de manera diferente, la abstracción de la creación de producta y ProductB en como muchas fábricas (un método por fábrica), y la mayor especialización de la pasos de creación será delegada a la jerarquía ya que está construido.

Si he creado un abstraída (referenciado a través de una interfaz o clase base abstracta) Clase de fábrica que crea objetos que sólo tiene un método para crear objetos, entonces sería una Método de fábrica .

Si el abstraída fábrica tenía más de 1 método para crear objetos, entonces sería un Abstract Factory .

Vamos a decir que hago un administrador que se encargará de las necesidades de los métodos de acción de un controlador MVC. Si tuviera un método, por ejemplo para crear los objetos de motores que se utilizarán para crear modelos de vista, entonces sería un patrón método de fábrica. Por otro lado si tuviera dos métodos: Uno. Para crear motores de vista del modelo, y otro para crear motores de modelos de acción (o como se quiera llamar el modelo que el método de acción contiene los consumidores), entonces sería una fábrica abstracta

public ActionResult DoSomething(SpecificActionModel model)
{
    var actionModelEngine = manager.GetActionModelEngine<SpecificActionModel>();
    actionModelEngine.Execute(SpecificActionModelEnum.Value);

    var viewModelEngine = manager.GetViewModelEngine<SpecificViewModel>();
    return View(viewModelEngine.GetViewModel(SpecificViewModelEnum.Value);
}

A pesar de que han pasado muchos años desde que la gente de Stackoverflow interrogados acerca de este tema de manera similar en otros puestos (más antiguo va a 2009), todavía no podía encontrar la respuesta que quería.


Así que hizo un par de horas de investigación a través de la web, revisar los ejemplos, y llegó a esta conclusión, las principales diferencias de Abstract Factory de Factory Method son

  • La intención: coherencia o "look-and-feel" . La intención de Abstract Factory es agrupar una familia de objetos con un mismo estilo (ex mismos widgets de interfaz de usuario look-and-feel, misma partes del estilo del coche, objetos de un mismo sistema operativo, etc.) Muchos ejemplos de Abstract Factory menciona acerca de la frase clave "el mismo aspecto y sensación".
  • Objetos formando un grupo objeto más grande . Abstract Factory crea una familia de objetos que forman un objeto de grupo más grande, ni un solo objeto
  • Más tarde añadir un nuevo estilo : Si seguimos utilizando el Método de fábrica y tratar de añadir un nuevo conjunto de estilo a la infraestructura existente, sería doloroso. Con Abstract Factory, todos tenemos que hacer es simplemente crear una nueva fábrica de hormigón que implementa la clase de fábrica abstracta.

Los ejemplos contrarios serían

  • Una pieza del coche de un coche deportivo utilizado en un sedán. Esta inconsistencia puede conducir a accidentes.
  • botón
  • Un estilo de Windows en diferentes widgets de interfaz gráfica de usuario del sistema operativo. No va a romper nada, pero la experiencia del usuario dolor para algunas personas, como yo.
  • Más tarde, nos damos cuenta de que nuestras necesidades de software que se ejecutan en la próxima actualización del sistema operativo que necesita un conjunto diferente de los objetos del sistema compatibles, manteniendo el software compatible con versiones anteriores.

Por lo tanto, cuando un grupo objetivo final debe tener el mismo estilo sin excepción de un objeto y que desea ocultar esta "mantener el mismo estilo" detalle, entonces debemos utilizar Abstract Factory.

Por lo que yo entiendo el significado o la fábrica abstracta y definiciones de métodos de fábrica el primero se lleva a cabo en un contexto estático y proporciona objeto en función de parámetros de entrada.

objeto segundo utiliza ya creado (la familia) que implementa la interfaz de fábrica método. El método de fábrica crea instancia específica relacionada con el objeto original no importa cuál se trata.

Por lo tanto, se producirá utilizando tanto los patrones juntos, donde en el primer paso que crear algún objeto general que describe la familia de objetos relacionados. Se llama por el método de método estático getInstance ( "nombre de mi familia"). La aplicación de tal método getInstance decide que se creará objeto familiar.

A continuación, llamo CreateProduct () en objetos de la familia de nueva creación y en función de objetos familiares del nuevo producto será devuelto.

Parece que estos patrones cooperan para cada uno.

En otras palabras Abstract Factory se centra en "qué" se creará y el método de fábrica "cómo" se creará.

Todo lo que tiene que recordar es que una fábrica abstracta es una fábrica que puede volver a múltiples fábricas . Así que si usted tenía un AnimalSpeciesFactory puede volver fábricas como esto:

Mamalfactory, BirdFactory, Fishfactory, ReptileFactory. Ahora que tiene una sola fábrica de la AnimalSpeciesFactory, que utilizan el patrón de fábrica para crear objexts específicos. Por ejemplo, imagina que tienes un ReptileFactory de esta AnimalFactory, entonces se podría ofrecer a crear objetos de reptiles como: Serpientes, tortugas, lagartos objetos.

Factory Method es un patrón de diseño creacional que se ocupa de la creación de objetos sin mostrar la clase exacta del objeto que se está creando. Este patrón de diseño, básicamente, permite a una clase aplaza la creación de instancias de subclases.

El patrón Abstract Factory sirve encapsulación de un grupo de fábricas individuales sin exponer las clases concretas. En este modelo, una interfaz genérica de una clase de fábrica abstracta se utiliza para crear el objeto de hormigón necesario separar los detalles de la implementación de los objetos de su uso y composición. Este patrón de diseño se utiliza ampliamente en aplicaciones GUI, donde el mismo tipo de necesidades componentes GUI que se creará.

mientras que la búsqueda en Google me ocurrió siguiente blog que explica tanto el patrón de diseño brillantemente. echar un vistazo a estos

http://simpletechtalks.com/factory-design-pattern/

http://simpletechtalks.com/abstract-factory-design-pattern/

/*
//Factory methods:

//1. Factory Method - Abstract Creator Class



#include <iostream>
#include <string.h>
using namespace std;

const std::string nineNintyCC = std::string("990CC");
const std::string thousandTwoHundredCC = std::string("1200CC");
const std::string ThousandFiveHundredCC = std::string("1500CC");
const std::string fiveThousandCC = std::string("5000CC");

// Product
class Engine
{
    public:
    virtual void packEngine() = 0;  
};

// Concrete products
// concrete product class one
class C990CCEngine: public Engine
{

    public:
    void packEngine()
    {
       cout << "Pack 990CC engine" << endl;   
    }
};

// concrete class Two
class C1200CCEngine: public Engine
{   public:
    void packEngine()
    {
        cout << "pack 1200CC engine" << endl;
    }

};

// Concrete class Three
class C1500CCEngine: public Engine
{
    public:
    void packEngine()
    {
        cout << "Pack 1500CC engine" << endl;
    }

};


// Car Factory:
class CarFactory{
    public:

    virtual Engine* createEngine(const std::string& type) = 0;
};
class Factory: public CarFactory
{
    public:
     Engine *createEngine(const std::string& type)
     {

          if(0 == nineNintyCC.compare(type))
          {    
             return new C990CCEngine;
          }
          else if(0 == thousandTwoHundredCC.compare(type))
          {
             return new C1200CCEngine;
          }
          else if(0 == ThousandFiveHundredCC.compare(type))
          {
             return new C1500CCEngine;
          } 
          else
           {
                 cout << "Invalid factory input" << endl;
             return NULL;
           }
           return NULL;
     }
};

int main()
{

    CarFactory* ptr = new Factory;
    Engine*pEngine =  ptr->createEngine(nineNintyCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine =  ptr->createEngine(ThousandFiveHundredCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine =  ptr->createEngine(thousandTwoHundredCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    pEngine = ptr-> createEngine(fiveThousandCC);
    if(pEngine)
    {
        pEngine->packEngine();
        delete pEngine;
    }
    else
    {
        cout << "No engine exists of your type in our factory" << endl;
    }
    return 0;
}

*/
/*
//
// interface product
#include <iostream>
#include <string>
using namespace std;

class Engine
{
 public:
 virtual void EngineType() = 0;

};

// concrte product
class AltoEngine: public Engine
{
  public:
  void EngineType()
  {
      cout << "Alto Engine" << endl;
  }
};

//Concrte product
class SwiftEngine : public Engine
{
    public:
    void EngineType()
    {
        cout << "Swift Engine" << endl;    
    }
};

class Body
{
   public:
    virtual void bodyType() = 0;

};

class AltoBody: public Body
{
  public:  
    virtual void bodyType()
    {
        cout << "Alto Car Body" << endl;
    }
};

class SwiftBody : public Body
{
    public:
    void bodyType()
    {
        cout << "SwiftCar Body" << endl;
    }

};


class CarFactory
{
   public:
   virtual Engine* createEngineProduct() = 0;
   virtual Body*   createBodyPoduct() = 0;
};
class AltoCarFactory: public CarFactory
{
    public:
    Engine * createEngineProduct()
    {
        return new AltoEngine;
    }
    Body* createBodyPoduct()
    {
        return new AltoBody;
    }

};

class SwiftCarFactory: public CarFactory
{
    public:
    Engine * createEngineProduct()
    {
        return new SwiftEngine;
    }
    Body* createBodyPoduct()
    {
        return new SwiftBody;
    }

};

int main()
{

    CarFactory* pAltoFactory = new AltoCarFactory;
    Engine* pAltoEngine = pAltoFactory->createEngineProduct();
    pAltoEngine->EngineType();
    Body* pAltoBody = pAltoFactory->createBodyPoduct();
    pAltoBody->bodyType();



    CarFactory* pSwiftFactory = NULL;
    pSwiftFactory = new SwiftCarFactory;
    Engine* pSwiftEngine = pSwiftFactory->createEngineProduct();
    pSwiftEngine->EngineType();
    Body* pSwfitBody = pSwiftFactory->createBodyPoduct();
    pSwfitBody->bodyType();
    delete pAltoBody;
    delete pAltoFactory;
    delete pSwfitBody;
    delete pSwiftFactory;
    return 0;
}
*/

/*

// One more Factory example;

#include <iostream>
#include <string>
using namespace std;

const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");
// Interface
class CarEngine
{
 public:
    virtual void engineType() = 0;
};

// Concrete class
class FiatEngine: public CarEngine
{
  public:
  void engineType()
  {
      cout << "Fait Engine Engine" << endl;
  }

};
// ConcreteClass
class RenaultEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Renault Engine" << endl;
    }

};
// Concrete class
class MaruthiEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Maruthi Engine" << endl;
    }
};


// Factory
class CarFactory
{
    public:
    virtual CarEngine* createFactory(const std::string&) = 0;
};

// EngineFactory
class CarEngineFactory : public CarFactory
{
     public:
     CarEngine* createFactory(const std::string&  type)
     {
          if(0 == maruthi.compare(type))
          {
              return new MaruthiEngine;

          }
          else if(0 == fiat.compare(type))
          {
              return  new FiatEngine;
          }
          else if(0 == renault.compare(type))
          {
              return new RenaultEngine;
          }
          else
          {
              cout << "Invalid Engine type" << endl;
              return NULL;
          }
     }

  };

int main()
{
    CarFactory* pCarFactory = new CarEngineFactory;
    CarEngine* pMaruthiCarEngine = pCarFactory->createFactory(maruthi);
    pMaruthiCarEngine->engineType();

    CarEngine* pFiatCarEngine = pCarFactory->createFactory(fiat);
    pFiatCarEngine->engineType();


    CarEngine* pRenaultCarEngine = pCarFactory->createFactory(renault);
    pRenaultCarEngine->engineType();

    return 0;
}


*/


/*

// One more Factory example;

#include <iostream>
#include <string>
using namespace std;

const std::string maruthi = std::string("Maruthi");
const std::string fiat = std::string("Fiat");
const std::string renault = std::string("Renault");


// Interface
class CarEngine
{
 public:
    virtual void engineType() = 0;
};

// Concrete class
class FiatEngine: public CarEngine
{
  public:
  void engineType()
  {
      cout << "Fait Car Engine" << endl;
  }

};

// ConcreteClass
class RenaultEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Renault Car Engine" << endl;
    }

};

// Concrete class
class MaruthiEngine : public CarEngine
{
    public:
    void engineType()
    {
        cout << "Maruthi Car Engine" << endl;
    }
};

// Interface
class CarBody
{
 public:
    virtual void bodyType() = 0;
};

// Concrete class
class FiatBody: public CarBody
{
  public:
  void bodyType()
  {
      cout << "Fait car Body" << endl;
  }

};

// ConcreteClass
class RenaultBody : public CarBody
{
    public:
    void bodyType()
    {
        cout << "Renault Body" << endl;
    }

};

// Concrete class
class MaruthiBody : public CarBody
{
    public:
    void bodyType()
    {
        cout << "Maruthi body" << endl;
    }
};


// Factory
class CarFactory
{
    public:
    virtual CarEngine* createCarEngineProduct() = 0;
    virtual CarBody* createCarBodyProduct() = 0;
};

// FiatFactory
class FaitCarFactory : public CarFactory
{
     public:
     CarEngine* createCarEngineProduct()
     {
        return new FiatEngine; 
     }
     CarBody* createCarBodyProduct()
     {
         return new FiatBody;
     }
};

// Maruthi Factory
class MaruthiCarFactory : public CarFactory
{
     public:
     CarEngine* createCarEngineProduct()
     {
         return new MaruthiEngine;
     }
     CarBody* createCarBodyProduct()
     {
         return new MaruthiBody;
     }

};

// Renault Factory
class RenaultCarFactory : public CarFactory
{
     public:
    CarEngine* createCarEngineProduct()
    {
        return new RenaultEngine;
    }

    CarBody* createCarBodyProduct()
    {
        return new RenaultBody;
    }

};


int main()
{

   // Fiat Factory
   CarFactory* pFiatCarFactory = new FaitCarFactory;
   CarEngine* pFiatEngine = pFiatCarFactory->createCarEngineProduct();
   CarBody*  pFiatBody = pFiatCarFactory->createCarBodyProduct();
   pFiatEngine->engineType();
   pFiatBody->bodyType();

   // Renault Car Factory
    return 0;
}

*/
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top