SHARE
Facebook X Pinterest WhatsApp

Design Patterns

Design Patterns: The Prototype Pattern Pattern Type: Creational Description The prototype design pattern seeks to provide a single unitary interface to a single class type, all while allowing the underlying class type to be different. This has a number of uses. For example, the GOF book illustrates the pattern through the use of a “Graphical […]

Written By
thumbnail
Peter Shaw
Peter Shaw
Jan 22, 2016
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

Design Patterns: The Prototype Pattern

Pattern Type: Creational

Description

The prototype design pattern seeks to provide a single unitary interface to a single class type, all while allowing the underlying class type to be different.

This has a number of uses. For example, the GOF book illustrates the pattern through the use of a “Graphical Object,” which can be used to create “Staves,” “Notes,” and “Time Signatures” in a music score editing application.

Underneath the hood, the client application can refer to everything as a “Graphical Object” that has a known set of methods and properties such as “Draw()” and “Colour,” but is capable of drawing very different objects using just those known base elements.

Another interesting example of its use could lie in an electronic logic simulator, where user circuits built up from lower level components could be loaded into the application, and used as sub circuits in a larger design.

Each circuit, irrespective of its underlying type, could be instantiated and represented as a “SubCircuit” but have drastically different inner workings under the covers.

Diagram

Proto
Figure 1: A client/prototype diagram

Client: This is the consumer requesting the prototype object

Prototype: This is an interface or an abstractly defined class representing the single class type

Concrete Prototype: These are the actual implementations returned by the prototype master

Implementation in C#

To implement the prototype design pattern, you need an interface or abstract class. This abstract class is the “Class Type” that consumers of the prototype object will create instances of. In the following example, these will be “Car Objects.”

The prototype itself, however, usually is just the “structure”. The actual implementations are provided by actual classes that either follow a contract-based interface, or are abstracted from the super object; in this example, “Race Car” and “Saloon Car.”

To start with, the main prototype may look something like the following:

namespace PrototypePattern
{
   public abstract class Car
   {
      public int TopSpeed { get; set; }
      public int EngineSize { get; set; }
      public string Colour { get; set; }

      public abstract Car Clone();
   }
}

Here, we stamp out the base class type, and make sure that the basic information we might hold is represented, and that we have in place a ‘Clone’ method to clone our object.

Concrete prototypes may then in turn look something like the following:

namespace PrototypePattern
{
   public class SportsCar : Car
   {
      public override Car Clone()
      {
         return this.MemberwiseClone() as Car;
      }

   }
}

You only need to implement the Clone operation to make this a prototypical instance, but the clone can have any manner of other options attached to it after the fact.

There is an inherent danger to be aware of, however, and that’s the subject of how deep the copy goes.

Memberwise Clone will create what is known as a shallow copy.

This means that your first level objects such as the “TopSpeed,” “EngineSize,” and “Colour” properties shown above will be copied faithfully into an entirely separate and new instance of the object when it’s cloned.

Any sub objects, however, will have their “Reference” cloned, but not an actual copy.

What this means in practice is that if you have any nested objects, which you then take a clone of as part of the parent object, a change to the property on the new clone will also update the same instance on the parent.

To make the clone work in a “Deep” fashion, you not only need to make a copy using a Memberwise clone, but you then need to “new” up a new copy of the sub object, then manually copy the values across, like so

      public override Car Clone()
      {
         var clone = this.MemberwiseClone() as Car;

         clone.embeddedObject = new EmbeddedObject();
         clone.embeddedObject.property =
            this.embeddedObject.property;

         return clone;
      }

Doing this ensures that you detach the embedded class from the copy attached to the master prototype, and then make sure it has the same values as previous.

In many cases, it makes more sense, especially under .NET, to use interfaces to create a prototypical instance. The pattern is closely related and in many ways a competitor to the “Abstract Factory” pattern. Generally, however when using the Prototype pattern you would manage object creation via a “Prototype Manager” that would keep close tracking on which patterns are used and where.

If you have a Design Pattern you’d like to see implemented in C#. drop me a comment below. Until next month, practice makes perfect.

Shawty

Recommended for you...

Different Types of JIT Compilers in .NET
Tariq Siddiqui
Mar 17, 2023
Middleware in ASP.NET Core
Tariq Siddiqui
Mar 16, 2023
Intro to Intel oneDAL and ML.NET
Hannes DuPreez
Jan 16, 2023
Types of Query Execution in LINQ
Tariq Siddiqui
Dec 15, 2022
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.