The prototype is built upon the use of object cloning. The prototype creates new
objects by cloning one of its concrete classes. The prototype is used in the
following situations:
- You need to hide the concrete product classes from the client.
- You want to reduce the number of classes to minimum.
- When you use dynamic loading.
- When you want to avoid using the complicated class hierarchy
of factories.
- When your class has a small amount of different state combinations.
The prototype pattern can help to speed up instantiation of objects because
copying objects is faster than constructing objects.
For a UML diagram of the pattern go to dofactory site.
Example in C#
Lets look at an example of prototype usage:
#region The Prototype
public abstract class Prototype<T>
{
#region Methods
public T Clone()
{
// create a shallow copy of the object
return (T)this.MemberwiseClone();
}
#endregion
}
#endregion
#region Prototype Concrete
public class ConcretePrototype :
Prototype<ConcretePrototype>
{
#region Members
private string _strName;
#endregion
#region Properties
/// <summary>
/// The name of the prototype
/// </summary>
public string Name
{
get
{
return _strName;
}
}
#endregion
#region Ctor
/// <summary>
/// Construct a new ConcretePrototype with the
/// given name.
/// </summary>
/// <param name="name">The given name</param>
public ConcretePrototype(string name)
{
_strName = name;
}
#endregion
}
#endregion
In the example I created a Prototype class which use the MemberwiseClone method
as the cloning implementation. You should remember that MemberwiseClone
makes a shallow copy of the object (copies object members). If you want a deep
copy you should implement it by yourself. The ConcretePrototype only adds
properties to the Prototype class.
Building Prototype Manager
You could build a manager to help you hold and handle the prototype concretes but
the manager isn't part of the pattern. An example of such a manager can look like:
#region Prototype Manager
/// <summary>
/// The manager isn't part of the design pattern
/// you can use it to manage concretes as a helper
/// class
/// </summary>
public class PrototypeManager
{
#region Members
private Dictionary<string, ConcretePrototype> concretes =
new Dictionary<string, ConcretePrototype>();
#endregion
#region Properties
/// <summary>
/// Indexer for the concretes which are hold
/// in the PrototypeManager
/// </summary>
public ConcretePrototype this[string name]
{
get
{
return concretes[name];
}
set
{
concretes.Add(name, value);
}
}
#endregion
}
#endregion
Summary
To sum up, the prototype pattern uses clone methods to make
application independent of how its products are created, composed
and represented. Prototype is easy to implement in C# because of the
MemberwiseClone method.
A note, the prototype and the abstract factory patterns are competing patterns.
Knowing how to implement design patterns helps to understand the trade off
of using each pattern and to choose the right pattern to use.