Prototype Design Pattern

Specifying the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. Instead of using new keyword to create objects, prototype design pattern will just copy the object created. It’s a clone. A photo copier would the best example in the real world that resembles this pattern.

JavaScript language implements this design pattern. The entire language itself. Everything you use in JavaScript is a clone.

When to Use:
  • When construction is expensive/take long time to process;
  • State is important. You want to copy states before it leaves off;
  • When you want to hide the constructor.
UML Class Diagram

Participants
Class/Interface Description
Prototype Interface or Abstract Class. It defines a method to clone an object
ConcretePrototype1, ConcretePrototype2  A class that implements the Prototype. It has a method to copy itself. Deep or shallow copy.
Client Consumes the Prototype

Sample Implementation
In this example, we are going to create a prototype that detects even numbers from 1 to N. A delay was included to assume that the process is expensive. Then we are going to clone the result.

Download Source Code


UML Class Diagram for Even Number Generator

Mapping
Prototype Design Pattern Even Number Generator
Prototype IEvenNumberGen.cs
ConcretePrototype EvenNumbersGenerator.cs
Client Program.cs

The Codes
IEvenNumberGen.cs
namespace PrototypeDesignPattern.EvenNumberGen
{
public interface IEvenNumberGen
{
void PrintEvenNumbers();
object Clone();
}
}
EvenNumbersGenerator.cs
using System;
using System.Collections.Generic;
using System.Threading;
namespace PrototypeDesignPattern.EvenNumberGen
{
class EvenNumbersGenerator : IEvenNumberGen, ICloneable
{
private int Numbers;
private List<int> EvenNumbers;
public EvenNumbersGenerator(int _numbers)
{
Numbers = _numbers;
DetermineEvenNumbers();
}
public void PrintEvenNumbers()
{
Console.WriteLine("\nEven Numbers");
foreach (int number in EvenNumbers)
{
Console.Write(String.Format("{0} ", number));
}
}
private void DetermineEvenNumbers()
{
EvenNumbers = new List<int>();
Console.Write("Processing:");
for (var Counter = 1; Counter < Numbers; Counter++)
{
Console.Write(".");
Thread.Sleep(50);
if ((Counter % 2) == 0)
{
EvenNumbers.Add(Counter);
}
}
}
public object Clone()
{
return MemberwiseClone();
}
}
}

Program.cs
using PrototypeDesignPattern.EvenNumberGen;
using System;
namespace PrototypeDesignPattern
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("\nEven Numbers Generator from the Original:\n");
IEvenNumberGen EvenNumberGen = new EvenNumbersGenerator(100);
EvenNumberGen.PrintEvenNumbers();
Console.WriteLine("\n\nEven Numbers from the Clone:\n");
IEvenNumberGen EvenNumberGenClone = EvenNumberGen.Clone() as EvenNumbersGenerator;
EvenNumberGenClone.PrintEvenNumbers();
Console.ReadKey();
}
}
}

The Output


If you you compare the original and the clone, the original processed the data and clone did not. It just copied the object.

I hope this is helpful. Drop some comments.