Creational Patterns

Factory Method

Also known as virtual constructor.

Problem

A class or framework can't anticipate the kind of objects it must create.

Solution

Structure

Behavior

Discussion

All products implement a common interface:

interface Product {...}

The creator class postpones decisions about what types of products are created by using a virtual constructor/abstract factory method:

abstract class Creator {
   //virtual constructor:
   abstract Product makeProduct();
   // etc.
}

A concrete creator replaces the abstract factory method with a concrete factory method. In this example the details of the concrete product are hidden as a private inner class:

class ConcreteCreator extends Creator {
   private class ConcreteProduct implements Product {...}
   Product makeProduct() { return new ConcreteProduct(); }
}

Generic Constructors

In C++ template parameters can represent constructors as well as classes, so generic constructors can be used to delay decisions about the types of products to create:

template<typename Product>
class Creator
{
public:
   // generic constructor:
   Product* makeProduct() { return new Product(); }
};

In this case there is no need to introduce an abstract Product base class. Here is how a client creates a concrete product:

Creator<ConcreteProduct> creator;
ConcreteProduct* p = creator.makeProduct();

Abstract Factory

Also called a kit.

Problem

An assembly can't anticipate the types of components it uses.

Solution

Structure

Behavior

Discussion

Assume abstract base classes are introduced for a family of related components/products:

class ComponentA {...};
class ComponentB {...};

An abstract factory/kit provides abstract factory methods for each of these components:

class Factory
{
public:
   virtual ComponentA* makeComponentA() = 0;
   virtual ComponentB* makeComponentB() = 0;
   // etc.
};

An assembly constructor can now be parameterized by a factory that makes the necessary components:

class Assembly
{
private:
   ComponentA* a;
   ComponentB* b;
   // etc.
public:
   Assembly(Factory* f)
   {
      a = f->makeComponentA();
      b = f->makeComponentB();
      // etc.
   }
};

Builder

Problem

We want to separate the construction of an assembly from the construction of its components.

Solution

Encapsulate the assembly construction process in a component called the director. Encapsulate the construction of the components in a component called the builder.

Structure

Behavior

Discussion

Builders are similar to abstract factories. There are two differences. First, the job of building the assembly is given to a component called the Director. Second, the components are created and added to the assembly by the builder.

Here is the abstract base class for all builders:

class Builder
{
protected:
   Assembly* a = 0;
public:
   virtual void addComponentA() = 0;
   virtual void addComponentB() = 0;
   // etc.
   Assembly* getAssembly() { return a; }
};

A concrete builder instantiates a concrete assembly and implements the methods for building and adding concrete components to this assembly:

class ConcreteBuilder: public Builder
{
private:
   class ConcreteComponentA: ComponentA { ... };
   class ConcreteComponentB: ComponentB { ... };
   class ConcreteAssembly: Assembly { ... };
public:
   ConcreteBuilder(){ a = new ConcreteAssembly(); }
   void addComponentA() { a->add(new ConcreteComponentA(); }
   void addComponentB() { a->add(new ConcreteComponentB(); }
};

The process for adding components to the assembly is implemented by the director:

class Director
{
public:
   void makeAssembly(Builder* b)
   {
      b->addComponentA();
      b->addComponentB();
      // etc.
   }
};

Here is how a client builds an assembly:

Builder* b = new ConcreteBuilder();
Director d;
d.makeAssembly(b);
Assembly a = b->getAssembly();

Singleton

Problem

Multiple instances of a class may not make sense or may create confusion.

Solution

Hide all constructors. Provide a static factory method that returns a pointer to the single instance of the class.

Structure

Behavior

Discussion

Assume an instance of the Manager class will be responsible for managing all components of an application. Having multiple managers could create confusion, so we hide all of the constructors. Java and C++ classes have a public implicit default constructor (i.e., a parameterless constructor) that must be made explicit and private. C++ classes also have an implicit copy constructor that must be made public.

class Manager
{
private:
   static Manager* theManager;
   Manager() { ... }
   Manager(const Manager& m) { }
   ~Manager() { }
public:
   // factory method:
   static Manager* makeManager()
   {
      if (!theManager) { theManager = new Manager(); }
      return theManager;
   }
   // etc.
};

Obviously the factory method and the pointer must be made static. In C++ memory must be allocated and initialized for the pointer separately:

Manager* Manager::theManager = 0;

Here is some sample client code:

Manager* m1 = Manager::makeManager();
Manager* m2 = Manager::makeManager(); // m1 == m2

delete m1; // error, destructor can't be called here
m1 = new Manager(); // error, constructor can't be called here

Assume the following function is declared:

void display(Manager m) { ... }

However calling the function isn't allowed:

display(*m1); // error, copy constructor can't be called here

Managers must be passed by reference:

void display(Manager& m) { ... }

Interning

A variation of the Singleton is Intern. Assume a class of

class Symbol
{
private:
   string name;
   Symbol()
  
   // etc.
};

class Intern
{
private:
   map<string, Symbol> symbols;
public:
   Symbol makeSymbol(string name)
   {
      map<string, Symbol>::iterator p;
      p = symbols.find(name);
     

Prototype

Smart factory methods.

Problem

We can't anticipate the types of the objects we wish to create at runtime.

Solution

The Prototype Pattern is like the factory method pattern. Instead of an abstract factory method a concrete factory method builds products based on product descriptions such as class names.

The basic idea is simple, although it sounds complicated. A Product base class maintains a static table that associates product descriptions with product prototypes. The factory method merely searches the table for a prototype. It then asks the prototype to clone itself and returns the clone.

Structure

 

Behavior

Discussion