//
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