Author image

Prototype Design Pattern


Difficulty:
1/5


Implementing Prototype Design Pattern like a boss and then laughing it off.
Bonus: coool way of spawning arrays of objects from a prototypical instance (check spawnMonsterArray).

The prototype pattern is a creational software design pattern, that is used when the type of object(s) to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to:

  • avoid subclasses of an object creator, like the factory pattern does
  • avoid the inherent cost of creating a new object in the standard way (like using new) when it can be prohibitively expensive for a given application

Design

  • define an abstract Prototype class with a clone() method that returns a copy of itself
  • create subclasses of Prototype . These will be the concrete types. Implement the clone method
  • create a Spawner/Factory class with a private Prototype pointer (sort of like the Queen bee who never leaves the hive) and a spawnObject() method. The Spawner class resembles a Prototype factory function. The spawnObject() method simply calls clone on its prototype object and returns it.
  • in the Spawner class call the prototype's clone method to return a copy of the prototype object based on the concrete subobject.

Notice there is a 1-to-1 relationship between a prototype and a factory/spawner. So create as many prototypical objects and their respective factory/spawner objects as the concrete subclasses you want to create.

Usage

  1. create the prototype(s): std::unique_ptr<Monster> skeletonPrototype = std::make_unique<Skeleton>();
  2. create the factory/spawner: std::unique_ptr<MonsterSpawner> skeletonFactory = std::make_unique<MonsterSpawner>( skeletonPrototype.get() );
  3. spawn a copy of the prototype object using the spawner: std::unique_ptr<Monster> skeleton = skeletonFactory->spawnMonster();
  4. or spawn multiple copies: auto skeletons = spawnMonsterArray<Skeleton>( skeletonFactory.get(), 10 );

The tricky aspect of this pattern in C++ is memory management & ownership of the objects. Thankfully, with C++11 onwards we have smart pointers and they can alleviate a large part of that burden. Still you have to make careful considerations concerning ownership. Create the prototypes as unique_ptrs, create the arrays/vectors as owners. On the other hand, the factories don't need to own anything, they simply make use of the passed pointer to do their thing. Give the code a careful read.

Prototype objects can be added and removed at run-time. One neat aspect about this pattern is that it doesn't just clone the class of the prototype, it clones its state too. This means we could make a spawner for fast ghosts, weak ghosts, or slow ghosts just by creating an appropriate prototype Ghost object.

I used Windows and Visual Studio 2017 to build the project.

Github

Github repository link. Snag up the code now!


0 likes