Applied Design Patterns with Java

Creational :: Prototype (117) {C ch 8}

Implementation

Prototype is particularly useful with static languages like C++, where classes are not objects, and little or no type information is available at run-time. Java has a runtime facility for indentifying type, Reflection (package java.lang.reflect) , and it does have a Cloneable interface, with a class Object.clone() method.

Consider the following issues when implementing prototypes:

  1. Using a prototype manager. When the number of prototypes in a system isn't fixed (that is, they can be created and destroyed dynamically), keep a registry of available prototypes. Clients won't manage prototypes themselves but will store and retrieve them from the registry. A client will ask the registry for a prototype before cloning it. This prototype manager is an associative store that returns the prototype matching a given key. It has operations for registering a prototype under a key and for unregistering it. Clients can change or even browse through the registry at run-time. This lets clients extend and take inventory on the system without writing code.
  2. Implementing the Clone operation. The hardest part of the Prototype pattern is implementing the Clone operation correctly. It's particularly tricky when object structures contain circular references. Most languages provide some support for cloning objects. Java does have a Cloneable interface, with a class Object.clone() method; this is 'shallow copy' cloning (the programmer must write a 'deep copy' clone method, if needed). Ensure that the clone's components are clones of the prototype's components. Cloning forces deciding what if anything will be shared.
  3. Initializing clones. While some clients handle the clone as is, others will want to initialize some or all of its internal state to specific values. Don't pass these values in the Clone operation, because their number will vary between classes of prototypes. Some prototypes might need multiple initialization parameters; others won't need any. Passing parameters in the Clone operation precludes a uniform cloning interface. It might be the case that prototype classes already define operations for (re)setting key pieces of state. If so, clients may use these operations immediately after cloning. If not, then introduce an Initialize operation that takes initialization parameters as arguments and sets the clone's internal state accordingly.


Related Patterns

Prototype and Abstract Factory (87) are competing patterns in some ways. They can also be used together, however. An Abstract Factory might store a set of prototypes from which to clone and return product objects.

Designs that make heavy use of the Composite (163) and Decorator (175) patterns often can benefit from Prototype as well.

Catalog Creational Prev Next