- 1. Goals
- 2. Problems
- 3. Discussion
- 4. Structure
- 5. Example
- 6. Control List
- 7. Rules of thumb
Goals
- Specify the types of objects to create using the prototype instance and create new objects by copying this prototype.
- Create one instance of the class to use as the source for all future instances.
- The new operator is considered harmful
Problems
An application is hard-wired to an object's class when using the new operator.
Discussion
Declare an abstract base class that defines a pure virtual method "clone" and maintains a dictionary of all "cloned" concrete derived classes. Any class that needs the "polymorphic constructor" capability: derives from an abstract base class, registers its prototypical instance, and implements the clone() operation.
The client then, instead of writing code that calls the new operator on the derived class name, invokes the "clone" operation on the abstract base class, providing a string or numbered data type that denotes the particular derived class desired.
Structure
The Factory knows how to find the right prototype, and each Class knows how to spawn new instances of itself.
Example
The Prototype template specifies the type of objects created using the prototype. Prototypes of new products are often built before full production, but in this example the prototype is passive and does not participate in copying. Mitotic cell division resulting in two identical cells is an example of a prototype that plays an active role in copying and thus exhibits a prototype pattern. When a cell splits, two identical genotype cells appear. In other words, the cell clones itself.
Control List
- Add "clone" method to existing class hierarchy
- Create a "registry" that maintains a cache of prototype objects. The registry can be encapsulated in a new Factory class or in a base class.
- Create a factory method that: may (or may not) take arguments, find the correct prototype object, call clone() on that object, and return the result.
- The client replaces all calls to the new operator with calls to the factory method.
Rules of thumb
- Sometimes the creation patterns are competitors: there are times when you can use Prototype or Abstract Factory. In other cases, they complement each other: An Abstract Factory can store a set of prototypes from which objects can be cloned and returned. Abstract Factory, Builder and Prototype can use Singleton in their implementations.
- Abstract Factory classes are often implemented using Factory Methods, but they can be implemented using Prototype.
- Factory method: creation through inheritance. Prototype: creation via delegation.
- Often projects start with Factory Method (less complex, customizable, subclasses proliferate) and evolve towards Abstract Factory, Prototype, or Builder (more flexible, more complex) as the developer finds more flexibility is needed.
- The prototype does not require subclasses, but it does require an "initialize" operation. A factory method requires subclassing but does not require initialization.
- Constructs that often use the Composite and Decorator patterns can often also use Prototype.
- The prototype creates one instance of the class to be used as the creator of all future instances.
- Prototypes are useful when object initialization is expensive and you expect minor changes to initialization parameters. In this context, Prototype can avoid costly "building from scratch" and support cheap cloning of a pre-initialized prototype.
- Prototype is unique among other creation patterns because it doesn't require a class - just an object. Object-oriented languages such as Self and Omega, which do away with classes, rely entirely on prototypes to create new objects.