Decorator Pattern in C# – Real-Time Example (Dynamic Behavior Addition)

What is Decorator Pattern?

The Decorator Pattern is a structural design pattern that adds new behavior to an object dynamically without modifying its original code.

It wraps the original object and extends its functionality.


Why Use Decorator Pattern?

  • Add features without changing existing code
  • Follow Open/Closed Principle
  • Avoid subclass explosion
  • Enable flexible combinations of behaviors

Real-Time Scenario

In an Invoice System:

  • Base amount = 1000
  • Add discount
  • Add tax
  • Add logging

👉 Instead of modifying Invoice, we decorate it


Implementation

Step 1: Component Interface


public interface IInvoice
{
    decimal GetAmount();
}

Step 2: Concrete Component


public class Invoice : IInvoice
{
    public decimal GetAmount() => 1000;
}

Step 3: Decorator (Add Behavior)


public class DiscountDecorator : IInvoice
{
    private readonly IInvoice _invoice;

    public DiscountDecorator(IInvoice invoice)
    {
        _invoice = invoice;
    }

    public decimal GetAmount()
    {
        return _invoice.GetAmount() - 100;
    }
}

Usage Example


IInvoice invoice = new Invoice();

// Add discount
invoice = new DiscountDecorator(invoice);

Console.WriteLine(invoice.GetAmount()); // 900

Multiple Decorators (Advanced)

Tax Decorator


public class TaxDecorator : IInvoice
{
    private readonly IInvoice _invoice;

    public TaxDecorator(IInvoice invoice)
    {
        _invoice = invoice;
    }

    public decimal GetAmount()
    {
        return _invoice.GetAmount() * 1.18m;
    }
}

Usage with Multiple Layers


IInvoice invoice = new Invoice();

// Apply discount first
invoice = new DiscountDecorator(invoice);

// Then apply tax
invoice = new TaxDecorator(invoice);

Console.WriteLine(invoice.GetAmount());

👉 Behaviors are stacked dynamically


Key Concept

Instead of:


class InvoiceWithDiscountAndTax : Invoice { }

We do:


new TaxDecorator(new DiscountDecorator(new Invoice()));

👉 Flexible composition over inheritance


Advantages

  • Add behavior without modifying original class
  • Flexible and dynamic feature addition
  • Avoids large inheritance hierarchies
  • Promotes reusable components

Disadvantages

  • Many small classes
  • Harder to debug layered objects
  • Can increase complexity

When to Use

  • When you need to add features dynamically
  • When modifying existing class is not allowed
  • When multiple combinations of features are required
  • When avoiding inheritance complexity

Real Project Mapping (.NET + Angular)

Feature Usage
Discount logic Decorator
Tax calculation Decorator
Logging Decorator
Validation pipeline Decorator

Pro Tip (Advanced .NET Usage)

  • Combine with Middleware pattern (ASP.NET Core pipeline)
  • Useful in cross-cutting concerns like logging, caching
  • Can integrate with DI for flexible composition

Summary

Decorator Pattern helps you:

  • Extend behavior dynamically
  • Keep core classes clean
  • Build flexible and scalable systems

👉 Perfect for pricing, logging, validation, middleware pipelines

Comments