Take advantage of the Decorator design pattern to add extensibility either dynamically or statically to your application Design patterns are solutions to recurring problems and complexities in software design and are classified into three distinct categories: creational, structural, and behavioral. The Decorator design pattern is a structural pattern and can be used to add functionality to an object dynamically sans the need of modifying the structure of the object. In essence, you can leverage the Decorator pattern to attach functionality or behavior to an object dynamically or statically sans the need to altering the object’s structure. Note that the Decorator design pattern follows the Open Closed Principle, one of the SOLID principles. Incidentally, the Open Closed Principle is used to design classes that are open for extensions but closed for modifications. Conformance to the Open Closed Principle facilitates building applications that are reusable and can be maintained easily. The Gang of Four (GOF) at Dofactory states: “Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.” A bit of code In this section we will explore how we can implement the Decorator design pattern in C#. The participants in a typical implementation of the Decorator design pattern include: Component — this represents the base type of the actual or the concrete type Concrete Component — this represents the concrete type that extends the base component. Note that the additional responsibilities or functionalities are added in this type. Decorator — this represents a reference to a component. The dynamic functionalities are added in this type. Now, let’s consider the following class. public abstract class Employee { public abstract string Display(); } Note that when using the Decorator design pattern, you extend the behavior of an existing class but it doesn’t necessarily mean that you have to use abstract types — the types may or may not be abstract. You can also implement the Decorator design pattern using interfaces, or even by using methods that are virtual in your concrete classes. In essence, you are not constrained to use only abstract classes when implementing the Decorator design pattern. We are using an abstract class here just for the sake of simplicity. The EmployeeConcrete class extends the Employee class and adds additional properties to it. Here’s how this class would look like. public class EmployeeConcrete : Employee { public string FirstName { set; get; } public string LastName { set; get; } public string Address { set; get; } public override string Display() { StringBuilder data = new StringBuilder(); data.Append("First name: " + FirstName); data.Append("nLast name: " + LastName); data.Append("nAddress: " + Address); return data.ToString(); } } The EmployeeDecorator class extends the Employee class, accepts an instance of the component class named Employee, and overrides the Display() method. Here’s how this class would look like. public class EmployeeDecorator : Employee { Employee employee = null; protected EmployeeDecorator(Employee employee) { this.employee = employee; } public override string Display() { return employee.Display(); } } Now that the component, concrete component and the decorator class is ready, you can now extend the EmployeeDecorator class to create a concrete decorator class. The following code listing shows how this class would look like. public class PermanentEmployeeDecorator : EmployeeDecorator { //Add properties relevant to a permanent employee private double PF { get; set; } public PermanentEmployeeDecorator(Employee employee) : base(employee) { } public override string Display() { return base.Display() + "nEmployee type: Permanent"; } } And, that’s all you need to do! You can now create an instance of PermanentEmployeeDecorator and use it as shown in the code snippet below. static void Main(string[] args) { EmployeeConcrete employeeConcrete = new EmployeeConcrete { FirstName = "Joydip", LastName = "Kanjilal", Address = "Hyderabad, India" }; PermanentEmployeeDecorator employeeDecorator = new PermanentEmployeeDecorator(employeeConcrete); Console.WriteLine(employeeDecorator.Display()); Console.Read(); } You can also have another type of employee — a contractual employee. To represent it, you would need to create another class named ContractEmployeeDecorator that extends the EmployeeDecorator class. Refer to the code snippet given below. public class ContractEmployeeDecorator : EmployeeDecorator { //Add properties relevant to a contract employee private double RatePerHour { get; set; } public ContractEmployeeDecorator(Employee employee) : base(employee) { } public override string Display() { return base.Display() + "nEmployee type: Contractual"; } } The following code snippet illustrates how you can use the ContractEmployeeDecorator class. static void Main(string[] args) { EmployeeConcrete employeeConcrete = new EmployeeConcrete { FirstName = "Joydip", LastName = "Kanjilal", Address = "Hyderabad, India" }; ContractEmployeeDecorator employeeDecorator = new ContractEmployeeDecorator(employeeConcrete); Console.WriteLine(employeeDecorator.Display()); Console.Read(); } Related content how-to How to use FastEndpoints in ASP.NET Core Take advantage of the free open-source FastEndpoints library to build fast and lean APIs in your ASP.NET Core applications. By Joydip Kanjilal Jul 11, 2024 7 mins Microsoft .NET C# Development Libraries and Frameworks how-to How to use Refit to consume APIs in ASP.NET Core Take advantage of Refit REST library to simplify API consumption and make your code cleaner, more efficient, and easier to maintain. By Joydip Kanjilal Jul 04, 2024 10 mins C# Microsoft .NET Software Deployment how-to When to use an abstract class vs. interface in C# Understanding the differences between an abstract class and interface is key to designing loosely coupled and extensible applications. By Joydip Kanjilal Jun 20, 2024 10 mins Small and Medium Business Microsoft .NET C# how-to 6 security best practices for ASP.NET Core Learn the best practices and built-in safeguards for preventing attacks and protecting sensitive data in your ASP.NET Core web applications. By Joydip Kanjilal Jun 07, 2024 6 mins C# Microsoft .NET Web Development Resources Videos