Factory Method Variants, Prototype Pattern, and Singleton Pattern (GoF Creational Patterns)

This section covers advanced Factory Method implementation techniques (parameterized factories, templates, lazy initialization), the complete Prototype pattern for creating objects by cloning prototypical instances, and the beginning of the Singleton pattern for ensuring a class has exactly one instance.

Key Concepts

Commands and Syntax

Parameterized Factory Method with parent delegation:


Product* MyCreator::Create(ProductId id) {
    if (id == YOURS) return new MyProduct;
    if (id == MINE)  return new YourProduct;
    if (id == THEIRS) return new TheirProduct;
    return Creator::Create(id); // delegate unhandled to parent
}

Lazy Initialization (avoid virtual calls in constructor):


Product* Creator::GetProduct() {
    if (_product == 0) {
        _product = CreateProduct();
    }
    return _product;
}

Template to avoid subclassing Creator:


template <class TheProduct>
class StandardCreator : public Creator {
public:
    virtual Product* CreateProduct() { return new TheProduct; }
};
StandardCreator<MyProduct> myCreator;

MazeGame with Factory Methods:


class MazeGame {
public:
    Maze* CreateMaze();
    virtual Maze* MakeMaze() const { return new Maze; }
    virtual Room* MakeRoom(int n) const { return new Room(n); }
    virtual Wall* MakeWall() const { return new Wall; }
    virtual Door* MakeDoor(Room* r1, Room* r2) const { return new Door(r1, r2); }
};

Prototype-based factory (MazePrototypeFactory):


class MazePrototypeFactory : public MazeFactory {
public:
    MazePrototypeFactory(Maze*, Wall*, Room*, Door*);
    virtual Wall* MakeWall() const { return _prototypeWall->Clone(); }
    virtual Door* MakeDoor(Room* r1, Room* r2) const {
        Door* door = _prototypeDoor->Clone();
        door->Initialize(r1, r2);
        return door;
    }
};

Clone with copy constructor:


Door* Door::Clone() const { return new Door(*this); }

Singleton structure:


class Singleton {
public:
    static Singleton* Instance(); // class-level access point
};

Naming convention: MacApp uses Class* DoMakeClass() for factory methods.

Relationships

Exam-Relevant Points