2
votes

definition of the abstract factory pattern: Provide an interface for creating families of related or dependent objects without specifying their concrete classes

  1. what does concreate classes means here ?
  2. Can anybody explain what does it mean creating a objects with out specifying thier concrete classes in abstract factory pattern means?
4
the very well explained stuff here :javapapers.com/design-patterns/abstract-factory-patternjmj

4 Answers

1
votes

If you are familiar with .NET check DbProviderFactory class. This single class provides abstraction on any database access. The class defines factory methods for creating database connection, database command, etc. All these methods again returns general abstract types. It is up to concrete implementation of the factory to return concrete implementation of connection class or command class dependent on particular database server / driver. For example SqlClientFactory returns SqlConnection, SqlCommand, etc. but OracleClientFactory creates OracleConnection, OracleCommand, etc. Simply by instancing the factory you get single point of access to all provider dependent classes.

1
votes

This Pattern is useful when client need to create objects which are somehow related . If we need to create the family of related or dependent object then we can use abstract factory pattern. There are following classes which we can use in this pattern:

AbstractFactory: declares an interface for operations that create abstract products

ConcreteFactory: implements the operations to create concrete product objects

AbstractProduct: declares an interface for a type of product object

Product: defines a product object to be created by the corresponding concrete factory implements the AbstractProduct interface

Client: uses interfaces declared by AbstractFactory and AbstractProduct classes

Here is the Implementation of Factory Design Pattern.

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();
       }
  }
0
votes

I think the pattern here is based on a set of classes. I've used this for sets of classes where the classes were related by how they access a database.

So I would have an abstract class called NWindAbstractFactory. This class would two abstract methods which would return an IProductRepository and an IOrderRepository. You couldn't implement anything directly, but your business logic was programmed against this abstract factory and interfaces.

I would then create concrete implementation of IProductRepository and IOrderRepository. Perhaps they were called SqlProductRepository and SqlOrderRepository. I could then create a concrete implementation of my abstract factory and it would be named something like NWindSqlFactory.

Maybe I would have another concrete factory called NWindXMLFactory which was able to create an XmlProductRepository and XmlOrderRepository.

I could then decide at runtime which implementation of my abstract factory I wanted to use. Maybe the NWindSqlFactory or NWindXMLFactory or maybe even NWindAccessFactory.

Again I think it works when you have a related set of classes but you don't want to program against the concrete implementation of them.

You could use a configuration setting which would use reflection to instantiate the actual implementation which you wanted. And you could do this with only one setting. You only need to specify the concrete factory--- because once you have the concrete factory, it can get all the other implementations.

0
votes

Consider The following simple code using Factory pattern concept:

#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. Now imagine if shape class was in shape.h, circle class was in circle.h and square class was in square.h, because of using factory pattern you don't actually need to include circle.h and square.h in main.cpp. Where as if you were not using Factory pattern, to make the square and circle instances in main you needed to have the square and circle concrete classes (i.e. square.h and circle.h) in the main.cpp.

  2. The reason you don't need to include those two files is because the creation of circle and square are moved from main.cpp to shape class in the create member function.