Understanding the Prototype Pattern in C# with Practical Examples

dazevedo

Daniel Azevedo

Posted on October 4, 2024

Understanding the Prototype Pattern in C# with Practical Examples

Hi devs,

When working with large systems, especially in enterprise-level applications like payroll or HR systems, it can be beneficial to clone objects instead of creating new ones from scratch. This is where the Prototype Pattern comes in handy. In this post, I’ll walk you through what the Prototype Pattern is and how it can be applied in a C# payroll system, using both shallow copy and deep copy.


What is the Prototype Pattern?

The Prototype Pattern is a creational design pattern that allows us to clone objects, effectively copying their properties without needing to instantiate them from scratch. It’s useful in situations where object creation is resource-heavy or when we need to keep the state of the object being cloned.


Key Concepts: Shallow Copy vs. Deep Copy

  • Shallow Copy: A shallow copy of an object duplicates only the top-level fields, meaning references within the object are copied by reference, not duplicated.
  • Deep Copy: A deep copy duplicates the object and all objects it references, ensuring that the new instance is independent of the original.

Applying the Prototype Pattern in a Payroll System

Let’s use an example based on salary processing in a human resources (HR) application. In this case, each Employee object has a Salary object associated with it.

Step 1: Define the Prototype Interface

First, we define an interface that will allow us to clone objects.

public interface IPrototype<T>
{
    T Clone();
}
Enter fullscreen mode Exit fullscreen mode

This interface guarantees that any class implementing it will provide a method to clone objects.


Step 2: Implement the Employee Class with Prototype

Here, we’ll create our Employee class, which has properties like Name and Salary. We’ll implement both shallow and deep copy methods.

public class Employee : IPrototype<Employee>
{
    public string Name { get; set; }
    public Salary Salary { get; set; }

    // Shallow copy
    public Employee Clone()
    {
        return (Employee)this.MemberwiseClone();
    }

    // Deep copy
    public Employee DeepClone()
    {
        Employee cloned = (Employee)this.MemberwiseClone();
        cloned.Salary = new Salary { Amount = this.Salary.Amount };
        return cloned;
    }
}

public class Salary
{
    public decimal Amount { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

Here:

  • Clone() provides a shallow copy of the Employee, meaning the Salary reference will still be shared between copies.
  • DeepClone() ensures that the Salary object is also cloned, making it a deep copy.

Step 3: Example of Using Shallow and Deep Copies

Let’s see how the Prototype Pattern can be used in a payroll context:

class Program
{
    static void Main()
    {
        // Original Employee
        Employee emp1 = new Employee
        {
            Name = "John",
            Salary = new Salary { Amount = 5000 }
        };
        Employee emp2 = emp1.Clone();
        emp2.Name = "Jane";
        emp2.Salary.Amount = 5500;  
        Employee emp3 = emp1.DeepClone();
        emp3.Name = "Bob";
        emp3.Salary.Amount = 6000; 
Console.WriteLine($"emp1: {emp1.Name}, Salary: {emp1.Salary.Amount}"); 
Console.WriteLine($"emp2: {emp2.Name}, Salary: {emp2.Salary.Amount}");  
Console.WriteLine($"emp3: {emp3.Name}, Salary: {emp3.Salary.Amount}"); 
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • After performing a shallow copy with emp2, any changes to emp2.Salary.Amount also affect emp1.Salary.Amount, because both employees share the same Salary reference.
  • With deep copy using emp3, changes to emp3.Salary.Amount do not affect emp1.Salary.Amount, because emp3 has its own separate Salary instance.

Why Use the Prototype Pattern?

This pattern can be especially useful in payroll systems or HR applications where object creation (e.g., creating multiple employees with similar data) can be repetitive and resource-intensive. Cloning can save time and reduce complexity.


Conclusion

The Prototype Pattern provides a flexible and efficient way to clone objects, allowing you to decide whether to perform a shallow or deep copy depending on your needs. In scenarios like salary processing or HR systems, this can reduce overhead and make code cleaner and more efficient.

Keep coding

💖 💪 🙅 🚩
dazevedo
Daniel Azevedo

Posted on October 4, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related