Prototype Design Pattern in C# with Example

1. Definition

The Prototype Pattern involves creating new objects by copying an existing object, known as the 'prototype'. It provides a mechanism to copy the original object's properties and produce a clone, ensuring a performance boost when instantiating objects is more resource-intensive than copying existing ones.

2. Problem Statement

Imagine you're designing a game where there are many objects with similar states or properties but slight differences. Initializing these objects traditionally might be resource-intensive, especially if they involve database reads or complicated calculations.

3. Solution

The Prototype pattern allows you to copy an existing object rather than creating a new instance from scratch, something that might be expensive or complex. By cloning a pre-configured prototype, you can reduce the need for new keyword instantiation, which might involve memory allocation, constructor execution, and other operations.

4. Real-World Use Cases

1. A game where specific enemies or terrain elements are generated repeatedly with slight differences.

2. A graphic editor where shapes drawn can be cloned and adjusted instead of being redrawn from scratch.

3. Initializing shared configurations or settings from a prototype for multiple application instances.

5. Implementation Steps

1. Create an abstract prototype class that declares a cloning method.

2. Implement a concrete prototype class that implements the cloning method, typically using MemberwiseClone in C#.

3. Use the clone method to replicate objects instead of creating new ones.

6. Implementation in C#

// Step 1: Abstract prototype class
public abstract class Shape
{
    public int X { get; set; }
    public int Y { get; set; }
    public string Color { get; set; }

    public abstract Shape Clone();
}

// Step 2: Concrete prototype class
public class Circle : Shape
{
    public int Radius { get; set; }

    public override Shape Clone()
    {
        return (Shape)this.MemberwiseClone();
    }
}

public class Program
{
    public static void Main()
    {
        Circle prototypeCircle = new Circle { X = 10, Y = 20, Color = "Red", Radius = 15 };

        Circle clonedCircle = prototypeCircle.Clone() as Circle;

        Console.WriteLine($"Original Circle - X: {prototypeCircle.X}, Y: {prototypeCircle.Y}, Color: {prototypeCircle.Color}, Radius: {prototypeCircle.Radius}");
        Console.WriteLine($"Cloned Circle - X: {clonedCircle.X}, Y: {clonedCircle.Y}, Color: {clonedCircle.Color}, Radius: {clonedCircle.Radius}");
    }
}

Output:

Original Circle - X: 10, Y: 20, Color: Red, Radius: 15
Cloned Circle - X: 10, Y: 20, Color: Red, Radius: 15

Explanation:

In the given example, an abstract Shape class is defined with properties and a Clone method declaration. 

The Circle class, inheriting from Shape, provides a concrete implementation of the Clone method. 

The Program class showcases the usage of the prototype pattern. Instead of creating a new Circle object from scratch, we clone an existing prototype. 

The output demonstrates that the cloned object retains the properties of the original.

7. When to use?

The Prototype pattern is beneficial when:

1. The classes to instantiate are specified at runtime.

2. Objects can have one of only a few different combinations of state, making it more efficient to clone a corresponding prototype than to instantiate a new object.

3. Initialization of an object is more costly than copying it.


Comments