Prototype Design Pattern in C#

Prototype Design Pattern in C# with Examples

In this article, I will discuss the Prototype Design Pattern in C# with Examples. Please read our previous article discussing the Fluent Interface Design Pattern in C# with Examples. The Prototype Design Pattern falls under the category of the Creational Design Pattern. At the end of this article, you will understand the following pointers:

  1. What is the Prototype Design Pattern?
  2. Example to Understand Prototype Design Pattern in C#.
  3. What is Object Cloning in C#?
  4. Example to Understand Object Cloning in C#.
  5. Real-Time Example to Understand Prototype Design Patterns in C#.
  6. Prototype Design Pattern UML (Class) Diagram.
  7. Advantages of Prototype Design Pattern.
  8. When to Use Prototype Design Pattern in C#?
What is the Prototype Design Pattern?

According to the GoF Definition, the Prototype Design Pattern specifies the kind of objects to create using a prototypical instance and creates new objects by copying this prototype.

The Prototype Design Pattern in C# is a creational pattern used for creating objects by copying an existing object, known as the prototype. This pattern is particularly useful when the cost of creating an object is more expensive or complex than copying an existing object.

To simplify the above definition, we can say that the Prototype Design Pattern gives us a way to create new or cloned objects from the existing object of a class. That means it clones the existing object with its data into a new object. If we make any changes to the cloned object (i.e., new object), it does not affect the original object.

Example to Understand Prototype Design Pattern in C#:

Let us understand the Prototype Design Pattern in C# with an example. In C#, when we try to copy one object to another using the assignment (=) operator, both objects share the same memory address. The reason is the assignment operator (=) copies the reference, not the object, except when there is a value type field. This operator will always copy the reference, not the actual object when working with the Reference type. Please have a look at the following image for a better understanding.

Copy one object to another object using the assignment (=) operator

As you can see in the above image, we have one class called Employee, having two properties, i.e., Name and Department. Within the Main method, first, we create an instance of the Employee class (i.e., emp1) and set values for Name and Department properties. Then, we create another employee instance (i.e., emp2) by assigning the existing employee object (i.e., emp1). When we change the Name property value of the emp2 object, it also changes the name of the emp1 object, and this is because both emp1 and emp2 share the same memory. So, remember that when we use the assignment (=) operator, it is Call-By-Reference only. The Complete Examples Code is given below.

using System;
namespace PrototypeDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Creating an Instance of Employee Class
            Employee emp1 = new Employee();
            emp1.Name = "Anurag";
            emp1.Department = "IT";

            // Creating another Instance of Employee with Existing Employee Instance using Assignment Operator
            // Both emp1 and emp2 share the same memory location as = Operator uses Call By Reference Mechanism
            Employee emp2 = emp1;

            // Changing the Name Property Value of emp2 instance, 
            // it will also change the Name Property Value of emp1 instance
            emp2.Name = "Pranaya";

            Console.WriteLine("Emplpyee 1: ");
            Console.WriteLine("Name: " + emp1.Name + ", Department: " + emp1.Department);
            Console.WriteLine("Emplpyee 2: ");
            Console.WriteLine("Name: " + emp2.Name + ", Department: " + emp2.Department);

            Console.Read();
        }
    }

    public class Employee
    {
        public string Name { get; set; }
        public string Department { get; set; }
    }
}
Output:

What is the Prototype Design Pattern?

What is Object Cloning in C#?

When we talk about Object Cloning in C#, it means it is all about the Call By Value. So, if we change one object, it will not affect the other. Let us see how to clone the object to another object. To do so, C# provides one method called MemberwiseClone, which will create a new complete copy of the object having a different memory. For a better understanding, please have a look at the below image.

What is Object Cloning in C#?

As shown in the above image, within the Employee class, we created one method, i.e., GetClone. As part of that method, we return a clone object using the MemberwiseClone method. Then, from the client code, we create a new instance of the Employee class and assign the properties with some values. Next, we create the second object by calling the GetClone method, which returns a new complete copy of the emp1 object. Now, both the objects (i.e., emp1 and emp2) are independent, and if we make any changes to any object, it will not affect other objects.

Note: Remember that the MemberwiseClone() method creates a shallow copy of the object. If your object contains other objects and you want a deep copy where even those internal objects are duplicated, you’d need to implement custom logic in the Clone() method. In our next article, we will discuss shallow and deep copies in detail.

Example to Understand Object Cloning in C#

The following code example shows how to create a Duplicate or Cloned Object from an Existing object using Object Cloning. 

using System;
namespace PrototypeDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Creating an Instance of Employee Class
            Employee emp1 = new Employee();
            emp1.Name = "Anurag";
            emp1.Department = "IT";

            // Instead of using Assignment Operator, now use the Clone method to create a Cloned Object
            // Both emp1 and emp2 having different Memory Address
            Employee emp2 = emp1.GetClone();

            // Changing the Name Property Value of emp2 instance, 
            // will not change the Name Property Value of emp1 instance
            emp2.Name = "Pranaya";

            Console.WriteLine("Emplpyee 1: ");
            Console.WriteLine("Name: " + emp1.Name + ", Department: " + emp1.Department);
            Console.WriteLine("Emplpyee 2: ");
            Console.WriteLine("Name: " + emp2.Name + ", Department: " + emp2.Department);

            Console.Read();
        }
    }

    public class Employee
    {
        public string Name { get; set; }
        public string Department { get; set; }

        public Employee GetClone()
        {
            // MemberwiseClone Method Creates a shallow copy of the current System.Object
            // So typecast the Object Appropriate Type
            // In this case, typecast to Employee type
            return (Employee)this.MemberwiseClone();
        }
    }
}
Output:

Example to Understand Object Cloning in C#

Points to Remember about the MemberwiseClone Method in C#:
  1. The MemberwiseClone method is part of the System.Object class and creates a shallow copy of the given object. 
  2. MemberwiseClone Method only copies the non-static fields of the object to the new object.
  3. In copying, if a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied, but the referenced object is not.

So, once we have understood Object Cloning, let us proceed further and understand how to implement Prototype Design Patterns in C# using Object Cloning.

Use Cases of Prototype Design Pattern in C#:

The Prototype pattern is particularly useful in scenarios where objects need to be created that are similar to existing objects or when object creation is more efficient through cloning than through standard constructors. This pattern is widely used in scenarios like loading templates or in systems where the performance impact of creating a new instance of a class is significant.

Real-Time Example to Understand Prototype Design Patterns in C#:

As we discussed, the Prototype Design Pattern in C# is used when we want to create a Duplicate or Cloned Object from an Existing object to enhance the application’s performance. That means we need to use this Prototype Design Pattern when creating an object is costly and complex. For Example, if you want to create an object after a costly database operation. Then, in that case, we can cache the object, return its clone on the next request, and update the database as and when needed, reducing the database interaction with our application. As a result, the performance will be improved.

Let us proceed and implement the Prototype Design Pattern in C# step by step. Once we implement the Prototype Design Pattern, we will see the UML Diagram and compare the Example with the Prototype Design Pattern UML (or Class) Diagram. So, first, create a class file with the name Employee.cs and then copy and paste the following code into it. The following class is the Prototype Abstract Class, which is used for the types of objects that can be cloned.

namespace PrototypeDesignPattern
{
    //The Prototype Abstract Class
    //This is an abstract class which is used for the types of object that can be cloned itself.
    public abstract class Employee
    {
        public string Name { get; set; }
        public string Department { get; set; }
        public string Type { get; set; }

        public abstract Employee GetClone();
        public abstract void ShowDetails();
    }
}

As you can see, the above class has few properties common with the next-level subclasses and two abstract methods that the child classes will implement. 

So, next, create a class file with the name PermanentEmployee.cs and then copy and paste the following code into it. Here, you can see that the class implements the Employee abstract class and provides implementations for the two abstract methods. In the GetClone method, we have written the logic to create a shallow copy of the current object. In our next article, we will discuss Shall Copy and Deep Copy in detail. 

using System;
namespace PrototypeDesignPattern
{
    //This is a class that implements the Prototype interface for cloning itself.
    public class PermanentEmployee : Employee
    {
        public int Salary { get; set; }
        public override Employee GetClone()
        {
            // MemberwiseClone Method Creates a shallow copy of the current System.Object
            // So typecast the Object Appropriate Type
            // In this case, typecast to PermanentEmployee type
            return (PermanentEmployee)this.MemberwiseClone();
        }

        public override void ShowDetails()
        {
            Console.WriteLine("Permanent Employee");
            Console.WriteLine($" Name:{this.Name}, Department: {this.Department}, Type:{this.Type}, Salary: {this.Salary}\n");
        }
    }
}

Next, create a class file named TemporaryEmployee.cs and copy and paste the following code. Here, you can see the class implements the Employee abstract class and provides implementations for the two abstract methods. In the GetClone method, we have written the logic to create a shallow copy of the current object. The following code is self-explained, so please go through the comment lines for a better understanding.

using System;
namespace PrototypeDesignPattern
{
    //This is a class that implements the Prototype interface for cloning itself.
    public class TemporaryEmployee : Employee
    {
        public int FixedAmount { get; set; }
        public override Employee GetClone()
        {
            // MemberwiseClone Method Creates a shallow copy of the current System.Object
            // So typecast the Object Appropriate Type
            // In this case, typecast to TemporaryEmployee type
            return (TemporaryEmployee)this.MemberwiseClone();
        }

        public override void ShowDetails()
        {
            Console.WriteLine("Temporary Employee");
            Console.WriteLine($" Name:{this.Name}, Department: {this.Department}, Type:{this.Type}, FixedAmount: {this.FixedAmount}\n");
        }
    }
}

We need to test whether the Clone Method works as expected within the Client code. In our example, the Main method of the Program class is nothing but the client. So, please modify the Main method of the Program class as follows. 

using System;
namespace PrototypeDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            // Creating an Instance of Permanent Employee Class
            Employee emp1 = new PermanentEmployee()
            {
                Name = "Anurag",
                Department = "IT",
                Type = "Permanent",
                Salary = 100000
            };

            //Creating a Clone of the above Permanent Employee
            Employee emp2 = emp1.GetClone();

            // Changing the Name and Department Property Value of emp2 instance, 
            // will not change the Name and Department Property Value of the emp1 instance
            emp2.Name = "Pranaya";
            emp2.Department = "HR";
            emp1.ShowDetails();
            emp2.ShowDetails();

            // Creating an Instance of Temporary Employee Class
            Employee emp3 = new TemporaryEmployee()
            {
                Name = "Preety",
                Department = "HR",
                Type = "Temporary",
                FixedAmount = 200000
            };

            //Creating a Clone of the above Temporary Employee
            Employee emp4 = emp3.GetClone();

            // Changing the Name and Department Property Value of emp4 instance, 
            // will not change the Name and Department Property Value of the emp3 instance
            emp4.Name = "Priyanka";
            emp4.Department = "Sales";
            emp3.ShowDetails();
            emp4.ShowDetails();
            
            Console.Read();
        }
    }
}
Output:

Real-Time Example to Understand Prototype Design Patterns in C#

Prototype Design Pattern UML (Class) Diagram:

Once we understand how to implement the Prototype Design Pattern in C#, let us try to understand the UML (Unified Modeling Language) or Class diagram of the Prototype Design Pattern. For a better understanding, please look at the following diagram, which shows the different components of the Prototype Design Pattern. Here, I am comparing the Prototype Design Pattern UML diagram with our example so that you can easily understand the different components of the Prototype Design Pattern.

Prototype Design Pattern UML (Class) Diagram

Let us understand each component of the Prototype Design Pattern:

  1. Prototype: This will be an interface or abstract class used for the types of objects that can be cloned. In our example, it is going to be the Employee Abstract Class.
  2. ConcretePrototype: This class will implement the Prototype abstract class or interface for cloning. In our example, it will be the PermanetEmployee and TemporaryEmployee Classes.
  3. Client: The client is the class that creates a new object by asking a prototype to clone itself.
Advantages of the Prototype Pattern:
  • Avoids Costly Creation: It’s useful when the cost of creating an object is more expensive or complex than cloning an existing object.
  • Encapsulates Complexities: The complexities and specifics of creating objects are encapsulated in the prototype.
  • Adds and Removes Objects at Runtime: You can add and remove objects at runtime.
  • Specifying New Objects: Clients can specify new objects by varying values from a prototype.
  • Reducing Subclassing: The pattern reduces the need for creating subclasses.
When to Use Prototype Design Pattern in C#?

The Prototype Design Pattern in C# is particularly useful in scenarios where:

  • Costly Object Creation: The instantiation of a class is a costly operation regarding resources and time, and you have an existing object similar to the one needed.
  • Avoiding Subclassing: When you want to avoid the complexities of subclassing hierarchies but still need to create objects similar to existing ones.
  • Dynamic System Configuration: If your system needs to be dynamic and able to generate new types of objects at runtime that are copies of predefined prototypes.
  • Preserving Initial State: In situations where you want to capture and preserve the state of an object at a point in time so that you can restore it later or replicate it.
  • Reducing Database Calls: In scenarios involving heavy database operations to fetch object states, a prototype can reduce these operations by cloning pre-loaded objects.
  • Complex Object Cloning: When deep copying or cloning complex objects is necessary, the Prototype pattern allows for a convenient way to achieve this, especially when objects have circular references or involve complex structures.
  • Object Population: In scenarios where many similar objects are needed, it’s more efficient to clone a prototype than to create each object from scratch.
Shallow vs. Deep Copy:

Shallow Copy: The MemberwiseClone method in C# performs a shallow copy. It copies the values of the fields of an object to a new object. If the field is a value type, a bit-by-bit copy of the field is performed. For reference types, the reference is copied, not the object itself.

Deep Copy: If your object has reference types fields, you might need to implement deep cloning to avoid shared references in your cloned objects. Deep cloning involves creating copies of the objects referenced by the fields.

While working with object cloning, we need to understand two things, i.e., Shallow Copy and Deep Copy. So, in the next article, I will discuss the Shallow Copy and Deep Copy in C# with Examples. In this article, I try to explain the Prototype Design Pattern in C# with Examples. I hope you understand the need and use of the Prototype Design Pattern in C# with Examples.

5 thoughts on “Prototype Design Pattern in C#”

  1. If you create the 2nd object by using new keyword, then you need to reassign the respective (same) values. No need for clone. it is cloning.

  2. How relevant is it to clone an object in the place of creation through any other Pattern ? Cloning will lead to performance degradation if it concerns the creation of a large number of small objects ????

Leave a Reply

Your email address will not be published. Required fields are marked *