//
Purpose. Abstract Factory #include <iostream.h>
//
//
Discussion. Trying to maintain class Widget { public:
//
portability across multiple "plat-
virtual void draw() = 0;
// forms" routinely requires lots
of };
// preprocessor
"case" stmts. The
//
Factory pattern suggests defining
class MotifBtn : public Widget {
// a creation services interface
in a public:
// Factory base
class, and implement- void draw() {
cout << "MotifBtn"
// ing each "platform" in a
separate << endl; }
// Factory derived class. };
#include
<iostream.h>
class WindowsBtn : public Widget {
public:
class Widget {
public: void draw()
{ cout << "WindowsBtn"
virtual void draw() = 0; << endl; }
}; };
class
MotifBtn : public Widget { class
Factory { public:
public: virtual Widget* createBtn() =
0;
void draw() { cout <<
"MotifBtn" };
<< endl; }
}; class
MotifFactory : public Factory {
public:
class
WindowsBtn : public Widget {
Widget* createBtn() {
public: return new MotifBtn; }
void draw() { cout <<
"WindowsBtn" };
<< endl; }
}; class
WindowsFactory : public Factory {
public:
void doThisWindow()
{ Widget*
createBtn() {
// create window,
attach btn return new
WindowsBtn; }
#ifdef MOTIF };
Widget* w = new MotifBtn;
#else // WINDOWS Factory*
factory;
Widget* w = new
WindowsBtn;
#endif void doThisWindow() {
w->draw(); } // create window, attach btn
Widget* w = factory->createBtn();
void doThatWindow() { w->draw(); }
// create window, attach btn
#ifdef
MOTIF void
doThatWindow() {
Widget* w = new
MotifBtn; // create
window, attach btn
#else // WINDOWS Widget* w =
factory->createBtn();
Widget*
w = new WindowsBtn;
w->draw(); }
#endif
w->draw(); }
void main( void )
{
void main( void
) #ifdef
MOTIF
{ factory = new
MotifFactory;
// create window,
attach btn #else //
WINDOWS
#ifdef MOTIF factory = new WindowsFactory;
Widget* w = new MotifBtn; #endif
#else // WINDOWS
Widget* w = new WindowsBtn; // create window, attach
btn
#endif Widget* w =
factory->createBtn();
w->draw(); w->draw();
doThisWindow(); doThisWindow();
doThatWindow(); doThatWindow();
} }
//
WindowsBtn //
MotifBtn
// WindowsBtn // MotifBtn
// WindowsBtn // MotifBtn
//
Purpose. Abstract Factory design
pattern demo.
//
// Discussion.
"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; }
};
void
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