Prototype Design Pattern using C#
Tags: csharp, designpatterns, programming, tutorial
Published: 2024-02-11 10:05:24

## Table of content
* Introduction
* Intent
* Participants
* Example
* Use Cases

##Introduction:
- The Prototype design pattern is a `Creational` design pattern.
- It is used to creating new objects by copying an existing object, known as the `prototype`. 
- This pattern is used when the `cost` of creating a new object is more `expensive` or `complex` than copying an existing one. 

##Intent:
- Specify the kind of objects to create using a prototypical instance, which is cloned to create new objects.
- Promote object creation that is efficient and independent of the concrete classes being instantiated.
- Avoid costly object creation operations by copying existing objects.

## Participants:
1. **Prototype** (_IPrototype_): This is an interface or an abstract class that defines a method for cloning itself. The Clone method is the key feature of this pattern.
2. **Concrete Prototype** (_ConcretePrototype_): Classes that implement the `IPrototype` interface. They provide concrete implementations of the `Clone` method.
3. **Client**: The client is responsible for creating new objects by requesting clones from a prototype. The client doesn't need to know the concrete class of the objects; it works with the `IPrototype` interface.

##Example:
Let's consider an example of a simple shape cloning system. We have an `IShape` interface representing shapes, and concrete shape classes implementing the Clone method to create new instances.
`Prototype`
 ```cs
// Prototype (IPrototype)
public interface IShape
{
    IShape Clone();
    void GetInfo();
}
```
`Concrete Prototype`
```cs
// Concrete Prototype (ConcretePrototype)
public class Rectangle : IShape
{
    private int width;
    private int height;

    public Rectangle(int width, int height)
    {
        this.width = width;
        this.height = height;
    }

    public IShape Clone()
    {
        return new Rectangle(width, height);
    }

    public void GetInfo()
    {
        Console.WriteLine($"Rectangle - Width: {width}, Height: {height}");
    }
}

 
public class Circle : IShape
{
    private int radius;

    public Circle(int radius)
    {
        this.radius = radius;
    }

    public IShape Clone()
    {
        return new Circle(radius);
    }

    public void GetInfo()
    {
        Console.WriteLine($"Circle - Radius: {radius}");
    }
}
```
`Usage`
```cs
IShape originalRectangle = new Rectangle(10, 20);
IShape clonedRectangle = originalRectangle.Clone();

IShape originalCircle = new Circle(5);
IShape clonedCircle = originalCircle.Clone();

originalRectangle.GetInfo();
clonedRectangle.GetInfo();

originalCircle.GetInfo();
clonedCircle.GetInfo();
```
`Output`
`Rectangle - Width: 10, Height: 20
Rectangle - Width: 10, Height: 20
Circle - Radius: 5
Circle - Radius: 5`

### Use Cases:

1. **`Efficient Object Creation`**: Use the Prototype pattern when the cost of creating an object is expensive (e.g., database calls or complex initialization) compared to cloning. Cloning can be a more efficient way to obtain new instances.
2. **`Configuration Management`**: When your application requires multiple instances with different configurations, the Prototype pattern can be used to create a base prototype object and clone it with different configurations.
3. **`Stateful Objects`**: If you need to create multiple instances of objects with internal state, using the Prototype pattern helps in preserving the internal state when cloning.
4. **`Reducing Subclass Proliferation`**: When you have a hierarchy of classes, the Prototype pattern can reduce the need for creating numerous subclasses by allowing dynamic object creation through cloning.