абстрактный фабричный образец - PullRequest
2 голосов
/ 23 мая 2011

определение шаблона абстрактной фабрики: предоставить интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов

  1. что означает здесь конкретный класс?Объясните, что означает создание объектов без указания их конкретных классов в абстрактных фабричных шаблонах?

Ответы [ 4 ]

1 голос
/ 22 апреля 2016

Этот шаблон полезен, когда клиенту нужно создавать объекты, которые так или иначе связаны между собой.Если нам нужно создать семейство связанных или зависимых объектов, мы можем использовать абстрактный шаблон фабрики.В этом шаблоне мы можем использовать следующие классы:

AbstractFactory: объявляет интерфейс для операций, которые создают абстрактные продукты

ConcreteFactory: реализует операции для создания конкретных объектов продукта

AbstractProduct: объявляет интерфейс для типа объекта продукта

Product: определяет объект продукта, который будет создан соответствующей конкретной фабрикой, реализует интерфейс AbstractProduct

Клиент: использует интерфейсы, объявленные AbstractFactory иАннотацияКлассы продукта

Вот реализация шаблона проектирования фабрики.

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();
       }
  }
1 голос
/ 23 мая 2011

Если вы знакомы с .NET, проверьте DbProviderFactory class.Этот единственный класс обеспечивает абстракцию при любом доступе к базе данных.Класс определяет фабричные методы для создания соединения с базой данных, команды базы данных и т. Д. Все эти методы снова возвращают общие абстрактные типы.Именно конкретная реализация фабрики возвращает конкретную реализацию класса соединения или класса команд, зависящих от конкретного сервера / драйвера базы данных.Например, SqlClientFactory возвращает SqlConnection, SqlCommand и т. Д., Но OracleClientFactory создает OracleConnection, OracleCommand и т. Д. Просто установив фабрику, вы получите единую точку доступа ко всем зависимым от провайдера классам.

0 голосов
/ 01 марта 2012

Рассмотрим следующий простой код, использующий концепцию шаблона Фабрики:

#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.h в main.cpp.Где, как если бы вы не использовали шаблон Factory, для создания экземпляров square и circle в main вы должны были иметь квадрат и кружок concrete classes (то есть square.h и circle.h) в main.cpp.

  2. Причина, по которой вам не нужно включать эти два файла, заключается в том, что создание circle и square перемещено из main.cpp в shape класс в create функция-член.

0 голосов
/ 23 мая 2011

Я думаю, что образец здесь основан на наборе классов. Я использовал это для наборов классов, где классы были связаны тем, как они обращаются к базе данных.

Поэтому у меня будет абстрактный класс с именем NWindAbstractFactory . Этот класс будет иметь два абстрактных метода, которые будут возвращать IProductRepository и IOrderRepository . Вы не могли ничего реализовать напрямую, но ваша бизнес-логика была запрограммирована на эту абстрактную фабрику и интерфейсы.

Я бы тогда создал конкретную реализацию IProductRepository и IOrderRepository. Возможно, они назывались SqlProductRepository и SqlOrderRepository . Затем я мог бы создать конкретную реализацию моей абстрактной фабрики, и она была бы названа примерно как NWindSqlFactory .

Возможно, у меня была бы другая конкретная фабрика с именем NWindXMLFactory , которая смогла создать XmlProductRepository и XmlOrderRepository .

Затем я мог бы решить во время выполнения, какую реализацию моей абстрактной фабрики я хотел бы использовать. Может быть, NWindSqlFactory или NWindXMLFactory или, может быть, даже NWindAccessFactory.

Опять же, я думаю, что это работает, когда у вас есть связанный набор классов, но вы не хотите программировать против их конкретной реализации.

Вы можете использовать параметр конфигурации, который будет использовать отражение, чтобы создать экземпляр фактической реализации, которую вы хотели. И вы можете сделать это только с одной настройкой. Вам нужно только указать конкретную фабрику --- потому что, имея бетонную фабрику, она может получить все остальные реализации.

...