抽象的工厂模式

时间:2011-05-23 18:35:36

标签: design-patterns

抽象工厂模式的定义:  提供用于创建相关或从属对象族的接口,而无需指定其具体类

  1. concreate类在这里意味着什么?
  2. 任何人都可以解释创建一个对象是什么意思,而不是在抽象工厂模式中指定他们的具体类意味着什么?

4 个答案:

答案 0 :(得分:1)

如果您熟悉.NET,请检查DbProviderFactory类。这个单一类提供了对任何数据库访问的抽象。该类定义了用于创建数据库连接,数据库命令等的工厂方法。所有这些方法再次返回一般抽象类型。由工厂的具体实现来决定返回依赖于特定数据库服务器/驱动程序的连接类或命令类的具体实现。例如,SqlClientFactory会返回SqlConnectionSqlCommand等,但OracleClientFactory会创建OracleConnectionOracleCommand等。只需通过实例化工厂即可获得单点访问所有提供者依赖类。

答案 1 :(得分:1)

当客户端需要创建以某种方式相关的对象时,此模式很有用。如果我们需要创建相关或依赖对象的族,那么我们可以使用抽象工厂模式。 我们可以在这种模式中使用以下类:

AbstractFactory:为创建抽象产品的操作声明一个接口

ConcreteFactory:实现创建具体产品对象的操作

AbstractProduct:声明一种产品对象的接口

产品:定义由相应的具体创建的产品对象 factory实现AbstractProduct接口

客户端:使用AbstractFactory和AbstractProduct类声明的接口

这是工厂设计模式的实现。

interface IWorst
    {
        string Name();
        string Cost();
        string Millage();
    }
    interface IBest
    {
        string Name();
        string Cost();
        string Millage();
    }
    class Splender : IWorst
    {
        public string Name()
        {
            return "Splender";
        }
        public string Cost()
        {
            return "40000 Rupees";
        }
        public string Millage()
        {
            return "70 KM/Lit";
        }
    }
    class platina : IWorst
    {
        public string Name()
        {
            return "Platina";
        }
        public string Cost()
        {
            return "35000 Rupees";
        }
        public string Millage()
        {
            return "90 KM/Lit";
        }
    }
    class Vector : IWorst
    {
        public string Name()
        {
            return "Victor Plus";
        }
        public string Cost()
        {
            return "38000 Rupees";
        }
        public string Millage()
        {
            return "80 KM/Lit";
        }
    }
    class Shine : IWorst
    {
        public string Name()
        {
            return "Shine";
        }
        public string Cost()
        {
            return "45000 Rupees";
        }
        public string Millage()
        {
            return "60 KM/Lit";
        }
    }
    class Karizma : IBest
    {
        public string Name()
        {
            return "Karizma ZMR";
        }
        public string Cost()
        {
            return "115000 Rupees";
        }
        public string Millage()
        {
            return "30 KM/Lit";
        }
    }
    class Plusar : IBest
    {
        public string Name()
        {
            return "Plusar 220";
        }
        public string Cost()
        {
            return "90000 Rupees";
        }
        public string Millage()
        {
            return "35 KM/Lit";
        }
    }
    class Apache : IBest
    {
        public string Name()
        {
            return "Apache 200";
        }
        public string Cost()
        {
            return "85000 Rupees";
        }
        public string Millage()
        {
            return "40 KM/Lit";
        }
    }
    class CBR : IBest
    {
        public string Name()
        {
            return "CBR 250";
        }
        public string Cost()
        {
            return "125000 Rupees";
        }
        public string Millage()
        {
            return "25 KM/Lit";
        }
    }
    interface iBikeFactory 
    {
        IBest GetBest();
        IWorst GetWorst();
    }
    class HeroFactory : iBikeFactory
    {
        public IBest GetBest()
        {
            return new Karizma();
        }
        public IWorst GetWorst()
        {
            return new Splender();
        }
    }
    class BajajFactory : iBikeFactory
    {
        public IBest GetBest()
        {
            return new Plusar();
        }
        public IWorst GetWorst()
        {
            return new platina();
        }
    }
    class TVSFactory : iBikeFactory
    {
        public IBest GetBest()
        {
            return new Apache();
        }
        public IWorst GetWorst()
        {
            return new Vector();
        }
    }
    class HondaFactory : iBikeFactory
    {
        public IBest GetBest()
        {
            return new CBR();
        }
        public IWorst GetWorst()
        {
            return new Shine();
        }
    }
    enum MANUFACTURERS
    {
        HERO,
        BAJAJ,
        TVS,
        HONDA
    }
    class BikeTypeChecker
    {
        iBikeFactory factory;
        MANUFACTURERS manu;
        public BikeTypeChecker(MANUFACTURERS m)
        {
            manu = m;
        }
        public void CheckProducts()
        {
            switch (manu)
            {
                case MANUFACTURERS.HERO:
                    factory = new HeroFactory();
                    break;
                case MANUFACTURERS.BAJAJ:
                    factory = new BajajFactory();
                    break;
                case MANUFACTURERS.TVS:
                    factory = new TVSFactory();
                    break;
                case MANUFACTURERS.HONDA:
                    factory = new HondaFactory();
                    break;
            }
            Console.WriteLine("\n"+manu.ToString() + ":\n\nBest Bike: " +
            factory.GetBest().Name() + "\nCost : " + factory.GetBest().Cost() + "\nMillage : " + factory.GetBest().Millage()+ "\n\nWorst Bike: " + factory.GetWorst().Name() + "\nCost : " + factory.GetWorst().Cost() +
            "\nMillage : " + factory.GetWorst().Millage());
        }
    }
    class MainApp
    {
        static void Main(string[] args)
        {
            BikeTypeChecker checker = new BikeTypeChecker(MANUFACTURERS.HERO);
            checker.CheckProducts();
            Console.ReadLine();
            checker = new BikeTypeChecker(MANUFACTURERS.BAJAJ);
            checker.CheckProducts();
            Console.ReadLine();
            checker = new BikeTypeChecker(MANUFACTURERS.HONDA);
            checker.CheckProducts();
            Console.ReadLine();
            checker = new BikeTypeChecker(MANUFACTURERS.TVS);
            checker.CheckProducts();
            Console.Read();
       }
  }

答案 2 :(得分:0)

我认为这里的模式基于一组类。我已经将它用于类的集合,其中类与它们访问数据库的方式有关。

所以我会有一个名为 NWindAbstractFactory 的抽象类。这个类有两个抽象方法,它们将返回 IProductRepository IOrderRepository 。您无法直接实现任何内容,但您的业务逻辑是针对此抽象工厂和接口进行编程的。

然后我将创建IProductRepository和IOrderRepository的具体实现。也许它们被称为 SqlProductRepository SqlOrderRepository 。然后,我可以创建一个抽象工厂的具体实现,它将被命名为 NWindSqlFactory

也许我会有另一个名为 NWindXMLFactory 的具体工厂,它能够创建 XmlProductRepository XmlOrderRepository

然后我可以在运行时决定我想要使用的抽象工厂的实现。也许是NWindSqlFactory或NWindXMLFactory,甚至可能是NWindAccessFactory。

我再次认为当你有一组相关的类但你不想针对它们的具体实现进行编程时它会起作用。

您可以使用配置设置,该设置将使用反射来实例化您想要的实际实现。你只需要一个设置就可以做到这一点。你只需要指定具体的工厂---因为一旦你拥有了具体的工厂,它就可以获得所有其他的实现。

答案 3 :(得分:0)

使用Factory模式概念考虑以下简单代码:

#include <iostream>
#include <string>

using namespace std;

// Abstract Base Class 
 class Shape {
     public:
        virtual void Draw() = 0;

        // Static class to create objects
        // Change is required only in this function to create a new object type
        static Shape* Create(string type);
 };

 class Circle : public Shape {
     public:
        void Draw() { cout << "I am circle" << endl; }
        friend class Shape; };

 class Square : public Shape {
     public:
        void Draw() { cout << "I am square" << endl; }
        friend class Shape; };

 Shape* Shape::Create(string type) {
     if ( type == "circle" ) return new Circle();
     if ( type == "square" ) return new Square();
     return NULL; }

 void main() { 

    // Give me a circle    
    Shape* obj1 = Shape::Create("circle");

    // Give me a square    
    Shape* obj2 = Shape::Create("square");

    obj1->Draw();    
    obj2->Draw(); 
 }

 OUTPUT: 
 I am circle 
 I am square
  1. 现在想象一下,如果形状类在shape.h中,则圆类位于circle.h而方形类位于square.h,因为使用了工厂模式,您不会实际上需要在circle.h中加入square.hmain.cpp。如果您没有使用工厂模式,要在main中制作方形和圆形实例,您需要在main.cpp中使用方形和圆concrete classes(即square.h和circle.h)。

  2. 您不需要包含这两个文件的原因是因为circlesquare的创建已从main.cpp移至shape create成员函数中的类。