BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 1.1+

Prototype Design Pattern

The prototype design pattern is a design pattern that is used to instantiate a class by copying, or cloning, the properties of an existing object. The new object is an exact copy of the prototype but permits modification without altering the original.

What is the Prototype Pattern?

The prototype pattern is a Gang of Four design pattern. This is a creational pattern as it is used to control class instantiation and object generation. The pattern is used to instantiate a new object by copying all of the properties of an existing object, creating an independent clone. This practise is particularly useful when the construction of a brand new object, using the new operator, is inefficient.

In general, when an object is cloned, the new object is either a shallow or deep copy. A shallow copy duplicates all of the object's properties. If any property contains a reference type, the reference is copied. This means that changes to the referenced object are visible in both the clone and the original object. A deep copy clones the main object and all child objects. Any properties of reference types are also cloned, giving a truly independent copy. The prototype pattern usually generates deep copies, though this is dependant upon the situation.

Implementing the Prototype Pattern

Prototype Design Pattern UML

The UML class diagram above describes an implementation of the prototype pattern. The classes in the diagram are as follows:

  • Prototype. This abstract class is the base class for the types of object that can be generated and cloned. The class contains a single virtual method named "Clone" that returns a Prototype object. This class can be replaced using an interface if no inheritable functionality is required. Indeed, the .NET framework includes a standard interface, named "ICloneable", for this purpose. However, as the Clone method of the ICloneable interface returns an object of the type System.Object, you may prefer to implement your own version.
  • ConcretePrototype (A/B). These classes inherit from the Prototype class and include any additional required functionality. They also override the Clone method to implement the duplication of their properties. There may be any number of concrete prototypes.

The following code shows the basic code of the prototype design pattern implemented using C#:

public abstract class Prototype
{
    public abstract Prototype Clone();
}


public class ConcretePrototypeA : Prototype
{
    public override Prototype Clone()
    {
        return (Prototype)MemberwiseClone();
    }
}


public class ConcretePrototypeB : Prototype
{
    public override Prototype Clone()
    {
        return (Prototype)MemberwiseClone();
    }
}

In the example code, the base class and two subclasses are shown. As this code shows only the basic structure of the pattern, no properties or fields have been defined so nothing will be copied during the cloning operation.

NB: The MemberwiseClone method creates shallow copies. For more complex objects that contain reference types, you will probably want to alter this to perform a deep copy.

Example Prototype

The prototype design pattern is generally used for complex classes or for classes that are costly to instantiate. In this example, we will use a simple class to keep the code to a manageable size. The base prototype class represents an employee of a business. This class incorporates two properties to hold the employee's name and role. It also, of course, includes the Clone method.

Two concrete classes are created to represent typists and software developers. Each inherits from the employee prototype base class and adds an extra property for the specific subclass. As both classes contain only value types and strings, it is acceptable to use MemberwiseClone for copying. If reference types were included and needed to be duplicated, rather than just copying the reference, manual cloning of each property would be required. Finally, the ToString method for each class is overridden to make it easier to output details of the objects.

NB: For brevity the properties are defined using the .NET 3.0 automatically implemented property syntax. For earlier versions of the .NET framework, these must be expanded.

public abstract class Employee
{
    public abstract Employee Clone();

    public string Name { get; set; }
    public string Role { get; set; }
}


public class Typist : Employee
{
    public int WordsPerMinute { get; set; }

    public override Employee Clone()
    {
        return (Employee)MemberwiseClone();
    }

    public override string ToString()
    {
        return string.Format("{0} - {1} - {2}wpm", Name, Role, WordsPerMinute);
    }
}


public class Developer : Employee
{
    public string PreferredLanguage { get; set; }

    public override Employee Clone()
    {
        return (Employee)MemberwiseClone();
    }

    public override string ToString()
    {
        return string.Format("{0} - {1} - {2}", Name, Role, PreferredLanguage);
    }
}
3 September 2008