Decorator Design Pattern attaches additional responsibility to an object dynamically. This pattern provides a flexible alternative to subclassing for extending functionality
The Decorator pattern allows behavior to be added to objects dynamically without altering their structure. It provides a flexible alternative to subclassing for extending functionality by wrapping objects in decorator classes that contain the same interface.
This implementation demonstrates a pizza ordering system where different toppings can be added to a base pizza:
- IPizza Interface: Common interface for both concrete pizzas and decorators
- PlainPizza (Concrete Component): The base pizza implementation
- PizzaDecorator (Base Decorator): Abstract decorator class that implements IPizza
- Concrete Decorators: ChickenPizzaDecorator and VegPizzaDecorator that add specific toppings
IPizza- Component interface with MakePizza() methodPlainPizza- Concrete component representing a basic pizzaPizzaDecorator- Abstract decorator class that wraps an IPizza objectChickenPizzaDecorator- Concrete decorator that adds chicken toppingVegPizzaDecorator- Concrete decorator that adds vegetable topping
PlainPizza plainPizza = new();
Console.WriteLine(plainPizza.MakePizza()); // "Plain Pizza"
PizzaDecorator chickenPizza = new ChickenPizzaDecorator(plainPizza);
Console.WriteLine(chickenPizza.MakePizza()); // "Plain Pizza, Chicken"
PizzaDecorator vegPizza = new VegPizzaDecorator(plainPizza);
Console.WriteLine(vegPizza.MakePizza()); // "Plain Pizza, Veg"
// Can also chain decorators
PizzaDecorator deluxePizza = new VegPizzaDecorator(chickenPizza);
Console.WriteLine(deluxePizza.MakePizza()); // "Plain Pizza, Chicken, Veg"- Adds functionality to objects without modifying their structure
- More flexible than static inheritance
- Allows for dynamic composition of behaviors
- Follows Single Responsibility Principle
- Supports unlimited combinations of decorators