Design patterns 设计模式:抽象工厂与工厂方法

Design patterns 设计模式:抽象工厂与工厂方法,design-patterns,language-agnostic,uml,factory-method,abstract-factory,Design Patterns,Language Agnostic,Uml,Factory Method,Abstract Factory,注:问题在文章末尾 我已经阅读了其他有关抽象工厂与工厂方法的stackoverflow线程。我理解每种模式的意图。但是,我不清楚这个定义 工厂方法定义了一个接口 用于创建对象,但让 子类决定选择哪一个 实例化。工厂方法允许 类将实例化推迟到 子类 相比之下,抽象工厂 提供一个用于创建 亲属或依亲家庭 对象而不指定其 具体课程 - 抽象工厂看起来非常类似于工厂方法。我画了几个UML类来说明我的观点 注: 该图来自www.yuml.com,因此它们没有完全定向。但这是一项免费服务:) 这些图表可能

注:问题在文章末尾

我已经阅读了其他有关抽象工厂与工厂方法的stackoverflow线程。我理解每种模式的意图。但是,我不清楚这个定义

工厂方法定义了一个接口 用于创建对象,但让 子类决定选择哪一个 实例化。工厂方法允许 类将实例化推迟到 子类

相比之下,抽象工厂 提供一个用于创建 亲属或依亲家庭 对象而不指定其 具体课程

-

抽象工厂看起来非常类似于工厂方法。我画了几个UML类来说明我的观点

注:

  • 该图来自www.yuml.com,因此它们没有完全定向。但这是一项免费服务:)
  • 这些图表可能并不完美。我仍在学习GoF的设计模式
工厂方法:

抽象工厂(仅1名成员):

抽象工厂(更多成员):

问题:

  • 如果抽象工厂只有一个创建者和一个产品,它仍然是抽象工厂模式吗?(用于创建族的界面)
  • 工厂方法是否可以从接口创建,还是必须从类创建?(类将实例化推迟到子类)
  • 如果抽象工厂只能有一个创建者和一个产品,抽象工厂工厂方法之间的唯一区别是前者的创建者是接口,后者的创建者是类吗

  • 这两种模式当然是相关的

    模式之间的区别通常在于意图

    工厂方法的意图是“定义一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法让类将实例化推迟到子类。”

    抽象工厂的意图是“提供一个接口,用于创建相关或从属对象的族,而无需指定它们的具体类。”

    纯粹基于这些意图陈述(引自GoF),我想说的是,实际上工厂方法在某种意义上是一个“退化的”抽象工厂,有一个家族

    它们通常在实现上有所不同,因为工厂方法抽象工厂简单得多

    然而,它们在实施中也有关联。正如GoF的书中提到的

    AbstractFactory仅声明用于创建产品的接口。实际创建它们取决于具体的产品子类。最常见的方法是为每个产品定义一个工厂方法


    这也有一些关于这个话题的有趣的讨论。

    希望这有帮助。它描述了各种类型的工厂。我用这本书作为参考书。我过去常画图表

    静态工厂

    是一个使用静态方法生成各种子类型产品的类

    简单工厂

    是一个可以生成各种子类型产品的类。(比静态工厂更好。添加新类型时,基本产品类不需要更改,只需更改简单的工厂类)

    工厂方法

    包含一种方法来生成与其类型相关的一种产品类型。(它比简单工厂好,因为类型被推迟到子类。)

    抽象工厂

    生成相关的类型族。它与工厂方法明显不同,因为它有多种类型的方法。(这很复杂,请参阅下一个图表以了解更好的实际示例)

    来自.NET框架的示例

    DbFactoriesProvider是一个简单的工厂,因为它没有子类型。DbFactoryProvider是一个抽象工厂,因为它可以创建各种相关的数据库对象,例如连接和命令对象


    ​​​

    如果我创建了一个抽象(通过接口或抽象基类引用)工厂类,该类创建的对象只有一个方法来创建对象,那么它将是一个工厂方法

    如果抽象工厂有多个方法来创建对象,那么它将是一个抽象工厂

    假设我制作了一个管理器,它将处理MVC控制器的动作方法需求。 如果它有一种方法,比如说创建用于创建视图模型的引擎对象,那么它将是一种工厂方法模式。 另一方面,如果它有两种方法:一种是创建视图模型引擎,另一种是创建动作模型引擎(或者任何你想调用动作方法包含消费者的模型的方法),那么它将是一个抽象工厂

    public ActionResult DoSomething(specific actionmodel)
    {
    var actionModelEngine=manager.GetActionModelEngine();
    actionModelEngine.Execute(SpecificActionModelEnum.Value);
    var viewmodelnengine=manager.getviewmodelnengine();
    返回视图(viewModelEngine.GetViewModel(SpecificViewModelEnum.Value);
    }
    
    就我理解抽象工厂和工厂方法定义的含义而言,第一个定义是在静态上下文中实现的,并基于输入参数提供对象

    第二种方法使用已经创建的对象(族),它实现了工厂方法接口。工厂方法然后创建与原始对象相关的特定实例
    /*
    //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;
    }
    
    */