Abstract Factory in C++
Why read if you can watch?
Watch Abstract Factory's video tutorialDiscussion. "Think of constructors as factories that churn out objects". Here we are allocating the constructor responsibility to a factory object, and then using inheritance and virtual member functions to provide a "virtual constructor" capability. So there are two dimensions of decoupling occurring. The client uses the factory object instead of "new" to request instances; and, the client "hard-wires" the family, or class, of that factory only once, and throughout the remainder of the application only relies on the abstract base class.
#include <iostream.h>
class Shape {
public:
Shape() { id_ = total_++; }
virtual void draw() = 0;
protected:
int id_;
static int total_;
};
int Shape::total_ = 0;
class Circle : public Shape { public:
void draw() { cout << "circle " << id_ << ": draw" << endl; } };
class Square : public Shape { public:
void draw() { cout << "square " << id_ << ": draw" << endl; } };
class Ellipse : public Shape { public:
void draw() { cout << "ellipse " << id_ << ": draw" << endl; } };
class Rectangle : public Shape { public:
void draw() { cout << "rectangle " << id_ << ": draw" << endl; } };
class Factory { public:
virtual Shape* createCurvedInstance() = 0;
virtual Shape* createStraightInstance() = 0;
};
class SimpleShapeFactory : public Factory { public:
Shape* createCurvedInstance() { return new Circle; }
Shape* createStraightInstance() { return new Square; }
};
class RobustShapeFactory : public Factory { public:
Shape* createCurvedInstance() { return new Ellipse; }
Shape* createStraightInstance() { return new Rectangle; }
};
int main() {
#ifdef SIMPLE
Factory* factory = new SimpleShapeFactory;
#elif ROBUST
Factory* factory = new RobustShapeFactory;
#endif
Shape* shapes[3];
shapes[0] = factory->createCurvedInstance(); // shapes[0] = new Ellipse;
shapes[1] = factory->createStraightInstance(); // shapes[1] = new Rectangle;
shapes[2] = factory->createCurvedInstance(); // shapes[2] = new Ellipse;
for (int i=0; i < 3; i++)
shapes[i]->draw();
}
ellipse 0: draw
rectangle 1: draw
ellipse 2: draw
