Objective 🎯
Allows to add/attach new features/behaviours to an object dynamically.
Notes 📝
This design pattern is also known as “Wrapper”.
Type ✅
❌Behavioral: Describes how objects interact/communicate between themselves.
❌Creational: Describes how to instantiate an object without large and complex.
✔️Structural: Describes how objects/classes are composed to form larger structures.
UML 📐
Participants 🔗
• Component:
- Defines the properties and methods for objects that can have responsibilities/features added to them dynamically
• Concrete Component:
- Implements Component interface
• Decorator:
- Maintains reference to a Component object
- Defines an interface that conforms to Component’s interface
• Concrete Decorator:
- Adds responsibilities to the component
Sample Code 🎮
Structural Example 🏛️
public static class DecoratorStructural
{
public static void Execute()
{
ConcreteComponent lConcreteComponent = new ConcreteComponent();
ConcreteDecoratorA lConcreteDecoratorA = new ConcreteDecoratorA();
ConcreteDecoratorB lConcreteDecoratorB = new ConcreteDecoratorB();
lConcreteDecoratorA.SetComponent(lConcreteComponent);
lConcreteDecoratorB.SetComponent(lConcreteDecoratorA);
lConcreteDecoratorB.Operation();
}
}
public abstract class Component
{
public abstract void Operation();
}
public class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("ConcreteComponent - Executing Operation");
}
}
public abstract class Decorator : Component
{
protected Component _Component;
public void SetComponent(Component prComponent)
{
_Component = prComponent;
}
public override void Operation()
{
if (_Component != null)
_Component.Operation();
}
}
public class ConcreteDecoratorA : Decorator
{
public override void Operation()
{
base.Operation();
Console.WriteLine("ConcreteDecoratorA - Executing Operation");
}
}
public class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
Console.WriteLine("ConcreteDecoratorB - Executing Operation");
}
}
Output
Real-world Example 🔥
public static class DecoratorPractical
{
public static void Execute()
{
Margherita lMargherita = new Margherita();
BarbequeDecorator lBarbequeDecorator = new BarbequeDecorator(lMargherita);
JalapenoDecorator lJalapenoDecorator = new JalapenoDecorator(lBarbequeDecorator);
Console.WriteLine(lJalapenoDecorator.GetDescription() + " | Cost: " + lJalapenoDecorator.GetCost());
Pepperoni lPepperoni = new Pepperoni();
BarbequeDecorator lBarbequeDecoratorPepperoni = new BarbequeDecorator(lPepperoni);
JalapenoDecorator lJalapenoDecoratorPepperoni = new JalapenoDecorator(lBarbequeDecoratorPepperoni);
OnionDecorator lOnionDecorator = new OnionDecorator(lJalapenoDecoratorPepperoni);
Console.WriteLine(lOnionDecorator.GetDescription() + " | Cost: " + lOnionDecorator.GetCost());
}
}
public abstract class PizzaItem
{
public string Name = "Unknown Pizza";
public string Description = "";
public abstract string GetDescription();
public abstract int GetCost();
}
public class Margherita : PizzaItem
{
public override string GetDescription() { return "Marguerita"; }
public override int GetCost() { return 20; }
}
public class Pepperoni : PizzaItem
{
public override string GetDescription() { return "Pepperoni"; }
public override int GetCost() { return 30; }
}
public abstract class ToppingDecorator : PizzaItem
{
protected PizzaItem _PizzaItem;
public ToppingDecorator(PizzaItem prPizzaItem)
{
_PizzaItem = prPizzaItem;
}
}
public class BarbequeDecorator : ToppingDecorator
{
public BarbequeDecorator(PizzaItem prPizzaItem) : base(prPizzaItem) { }
public override string GetDescription() { return _PizzaItem.GetDescription() + ", Barbeque"; }
public override int GetCost() { return _PizzaItem.GetCost() + 5; }
}
public class JalapenoDecorator : ToppingDecorator
{
public JalapenoDecorator(PizzaItem prPizzaItem) : base(prPizzaItem) { }
public override string GetDescription() { return _PizzaItem.GetDescription() + ", Jalapeno"; }
public override int GetCost() { return _PizzaItem.GetCost() + 5; }
}
public class OnionDecorator : ToppingDecorator
{
public OnionDecorator(PizzaItem prPizzaItem) : base(prPizzaItem) { }
public override string GetDescription() { return _PizzaItem.GetDescription() + ", Onion"; }
public override int GetCost() { return _PizzaItem.GetCost() + 5; }
}
Output
This is what happens when we decorate the Pepperoni Pizza: