Tuesday, May 20, 2008

C++ Factory Pattern

Tuesday, May 20, 2008

Factory Pattern

  • Factory pattern is a creational design pattern.
  • Idea of the factory patterns is to localize the object creation code.
  • This prevents disturbing the entire system for a new type introduction.
  • Typically when a new type is introduced in the system, change is at one place only where the object is created to decide which constructor to use.
  • Simplest of the factory is introduction of a static method in the base class itself, which creates the required object based on the type.
  • Other variant is Abstract Factory.
  • Concrete classes are isolated.
  • Client need not event know which class is implementing its need.

Static factory - Sample Program

#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

Abstract Factory - Sample Program

#include <iostream>
#include <string>

using namespace std;

// Abstract base class
class Mobile {
    public:
       virtual string Camera() = 0;
       virtual string KeyBoard() = 0;

       void PrintSpecs() {
          cout << Camera() << endl;
          cout << KeyBoard() << endl;
       }
};

// Concrete classes
class LowEndMobile : public Mobile {
    public:
       string Camera() {
          return "2 MegaPixel";
       }

       string KeyBoard() {
          return "ITU-T";
       }
};

// Concrete classes
class HighEndMobile : public Mobile {
    public:
       string Camera() {
          return "5 MegaPixel";
       }

       string KeyBoard() {
          return "Qwerty";
       }
};


// Abstract Factory returning a mobile
class MobileFactory {
    public:
       Mobile* GetMobile(string type);
};

Mobile* MobileFactory::GetMobile(string type) {
    if ( type == "Low-End" ) return new LowEndMobile();
    if ( type == "High-End" ) return new HighEndMobile();
    return NULL;
}


void main()
{
   MobileFactory* myFactory = new MobileFactory();

   Mobile* myMobile1 = myFactory->GetMobile("Low-End");
   myMobile1->PrintSpecs();

   Mobile* myMobile2 = myFactory->GetMobile("High-End");
   myMobile2->PrintSpecs();
}

OUTPUT:
2 MegaPixel
ITU-T
5 MegaPixel
Qwerty

23 comments:

  1. I use the factory implemented in PapaFactory. It has some great features.

    ReplyDelete
  2. what about the deallocation of Shape * obj1, obj2?????

    ReplyDelete
    Replies
    1. Making sure to deallocate memory after you're done with it is always a best practice. However, if you do not deallocate it within the code, the memory will be automatically deallocated once your program terminates and closes. With a small example like this, you can get away with not deallocating it in the code.

      That said, it's still always best to do it in the code anyways. If you ever decided to reuse your code, or go back later and extend your program, you could end up with memory leaks.

      Delete
  3. Yes, would you please explain who is responsible to delete those new obj.

    Thank you.

    ReplyDelete
  4. Actually cleaning up the code is up-to the user , the job of the author is to emphasize and explain the algorithm . (which he has done a terrific job). Most readers prefer a small code which they feel doesn't deviate them from the subject..thats why the author probably has neglected the clean ups...

    ReplyDelete
  5. Thanks Mahesh, Keep posting other pattern too with such simple examples which can be easily understandable.

    ReplyDelete
  6. seems less useful in C++ (with no garbage collection) compared to C# or JAVA

    ReplyDelete
  7. Its really great...

    ReplyDelete
  8. This is the best demonstration so far !!

    ReplyDelete
  9. You have to use a virtual destructor in the classes for the destruction of objects.

    ReplyDelete
  10. If I were to seperate interface from implementation in the first example, where would the create method be located (i.e. in what file)?

    ReplyDelete
  11. First, In main() the following code will produce the same results:

    Mobilefactory myFactory;
    Mobile* obj=myFactory.GetMobile("Low-End");
    obj->Printspecs();

    Why not use this way? It seems more natural.


    Second, why not make GetMobile static in the class MobileFactory? such as:

    class MobileFactory {
    public:
    Static Mobile* GetMobile(string type);
    };

    ReplyDelete
  12. Very good example!
    I have a related question: How can I adjust the size of the object that is returned by myFactory->GetMobile ? In my case LowEndMobile and HighEndMobile have a data structure like

    class LowEndMobile : public Mobile {
    public:
    string Camera() {
    return "2 MegaPixel";
    }

    string KeyBoard() {
    return "ITU-T";
    }

    float a[3];
    };

    ReplyDelete
  13. Nice post. I like the idea of Factory method, It gives more control on maintenance part of software life cycle. even Josua Bloach has suggested importance of static factory method in Effective Java. I have also blogged about factory method pattern in Java, let me know how do you find it.

    ReplyDelete
  14. Good example..Clearly explained

    ReplyDelete
  15. explanation is good. but Shape is an abstract class. how can u create an object for shape in main?

    ReplyDelete
    Replies
    1. author is not creating object for shape in main. he is creating pointer of type shape. He is then assigning object of type circle or square based on the string passed into getShape function.

      Delete
  16. is declaring Shape as a friend class of Circle & Square really necessary for the factory example?

    ReplyDelete
  17. Nicely explained. Such an simple explanation to understand. Thank you very much.

    ReplyDelete
  18. In Abstract Factory example, where is abstract factory? Below mentioned method must be equated to zero:
    Mobile* GetMobile(string type);
    It should be-
    Mobile* GetMobile(string type) = 0;

    ReplyDelete

 

© 2013, 2014 Programming Tutorials by SourceTricks. All rights resevered. Designed by Templateism

Back To Top