Introduction
The Prototype Design Pattern is a creational design pattern that allows new objects to be created by copying an existing object (called a prototype) instead of creating them from scratch.
This pattern is particularly useful when:
- Object creation is expensive or complex.
- Many similar objects need to be created.
- You want to avoid repeatedly initializing the same data.
Instead of using constructors every time, the application clones an existing object and modifies only the necessary properties.
Understanding the Prototype Pattern
The Prototype pattern works around a simple idea:
"Create new objects by cloning existing objects."
A prototype object acts as a template. When a new object is needed, the application copies the prototype and customizes it.
Structure
The following class diagram illustrates the Prototype Pattern:
Components:
- Prototype (BasicCar)
- Declares a cloning method.
- Defines the common interface for cloning.
- Concrete Prototypes (Nano, Ford)
- Implement the cloning operation.
- Return copies of themselves.
- Client (Program)
- Uses prototypes to create new objects.
Prototype Pattern Example in C
Abstract Prototype
public abstract class BasicCar
{
public string ModelName { get; set; }
public int Price { get; set; }
public static int SetPrice()
{
int price = 0;
Random r = new Random();
int p = r.Next(200000, 500000);
price = p;
return price;
}
public abstract BasicCar Clone();
}
Explanation
BasicCar acts as the prototype base class.
It contains:
- Common properties (
ModelName,Price) - A utility method for generating random prices
- An abstract
Clone()method that subclasses must implement
Concrete Prototype: Ford
public class Ford : BasicCar
{
public Ford(string m)
{
ModelName = m;
}
public override BasicCar Clone()
{
return (Ford)this.MemberwiseClone();
}
}
Explanation
The Ford class inherits from BasicCar and implements the cloning logic.
return (Ford)this.MemberwiseClone();
This creates a copy of the current object using the built-in MemberwiseClone() method.
Client Code
Console.WriteLine("***Prototype Pattern Demo***\n");
// Base or Original Copy
BasicCar nano_base = new Nano("Green Nano")
{
Price = 100000
};
BasicCar ford_base = new Ford("Ford Yellow")
{
Price = 500000
};
BasicCar bc1;
// Nano Clone
bc1 = nano_base.Clone();
bc1.Price = nano_base.Price + BasicCar.SetPrice();
Console.WriteLine(
"Car is: {0}, and it's price is Rs. {1}",
bc1.ModelName,
bc1.Price);
// Ford Clone
bc1 = ford_base.Clone();
bc1.Price = ford_base.Price + BasicCar.SetPrice();
Console.WriteLine(
"Car is: {0}, and it's price is Rs. {1}",
bc1.ModelName,
bc1.Price);
Console.ReadLine();
How the Program Works
Step 1: Create Prototype Objects
BasicCar nano_base = new Nano("Green Nano");
BasicCar ford_base = new Ford("Ford Yellow");
These objects become the prototypes.
Step 2: Clone Instead of Creating
bc1 = nano_base.Clone();
Rather than creating a new Nano, we copy the existing one.
Step 3: Customize the Clone
bc1.Price = nano_base.Price + BasicCar.SetPrice();
The cloned object receives a different price while keeping the original model information.
Step 4: Repeat for Other Car Types
bc1 = ford_base.Clone();
The same cloning mechanism works for any prototype implementation.
Understanding MemberwiseClone()
The Prototype pattern in C# often relies on:
this.MemberwiseClone();
MemberwiseClone() is a protected method of System.Object.
It creates a shallow copy of the current object.
var copy = this.MemberwiseClone();
What Gets Copied?
Value Types
int
bool
double
struct
These are copied by value.
Original ----> 100
Clone ----> 100
Changes to one do not affect the other.
Reference Types
List<string>
Address
Customer
Array
Only the reference is copied.
Original ---> Address Object
Clone ------^
Both objects point to the same instance.
Shallow Copy vs Deep Copy
The following comparison summarizes the difference:
| Type | Meaning |
|---|---|
| Shallow Copy | Copies fields, but references stay shared |
| Deep Copy | Creates completely independent copies of all nested objects |
Shallow Copy
public Person Clone()
{
return (Person)this.MemberwiseClone();
}
Result:
Person A ---> Address
Person B ---^
Both persons share the same address object.
Deep Copy
public Person DeepClone()
{
var copy = (Person)this.MemberwiseClone();
copy.Address = new Address
{
City = this.Address.City
};
return copy;
}
Result:
Person A ---> Address A
Person B ---> Address B
Now each object has its own independent nested objects.
Is MemberwiseClone() Safe?
Yes, when:
- Objects contain only value types.
- Shared references are acceptable.
- You manually clone reference-type members afterward.
Be Careful When:
- Objects contain collections.
- Objects contain nested objects.
- Complete independence is required.
In those situations, implement a deep clone.
Benefits of the Prototype Pattern
1. Faster Object Creation
Cloning is often faster than constructing and initializing complex objects.
2. Reduces Repeated Initialization
Objects with many properties can be copied rather than rebuilt.
3. Simplifies Object Creation
Clients don't need to know all construction details.
4. Supports Runtime Object Creation
New objects can be created dynamically from existing prototypes.
Drawbacks
1. Deep Cloning Can Be Complex
Nested object graphs require extra cloning logic.
2. Shared References Can Cause Bugs
Using shallow copies incorrectly may lead to unexpected side effects.
3. Maintenance Overhead
Every new field may require updates to deep-cloning logic.
When Should You Use the Prototype Pattern?
Use Prototype when:
✅ Object creation is expensive
✅ Many similar objects are required
✅ Initialization logic is complex
✅ You need runtime object duplication
Examples include:
- Game character templates
- Vehicle configurations
- Document templates
- UI component libraries
- Product catalogs
Conclusion
The Prototype Design Pattern is a powerful creational pattern that creates new objects by cloning existing ones. In C#, it is commonly implemented using MemberwiseClone(), which provides a fast and efficient way to perform shallow copies.
For simple objects, shallow cloning is often sufficient. However, when objects contain nested reference types, a deep clone should be implemented to ensure complete independence between the original object and its clone.
In the car example, Nano and Ford act as concrete prototypes, while BasicCar defines the cloning contract. The client can create new car instances efficiently by cloning existing prototypes instead of constructing them from scratch.

Top comments (0)