top of page
Writer's pictureamol ankit

Pouring Elegance into Code: With the Decorator Pattern

Brewing Code Elegance with the Decorator Pattern


Welcome, fellow coders! Today, let's embark on a journey through the aromatic realms of design patterns, with a particular focus on the Decorator Pattern with the help of C#. If you've ever found yourself yearning for a flexible and elegant way to enhance the functionality of your classes, the Decorator Pattern might just be the secret ingredient you've been searching for.



Decorating coffee with milk
Decorating coffee with additional details


Components of Decorator Pattern (Ingredients)


In our quest for code elegance, we begin with the essential components of the Decorator Pattern:


Component Interface (ICoffee)

public interface ICoffee
{
    int Cost();
}

This is the blueprint, defining the core functionality that both concrete components and decorators will adhere to. In our scenario, it's the `ICoffee` interface with a `Cost` method.


Concrete Component (SimpleCoffee)

public class SimpleCoffee : ICoffee
{
    public int Cost()
    {
        return 10;
    }
}

Our journey starts with a simple coffee implementation, adhering to the `ICoffee` interface and providing a base cost.


Decorator (CoffeeDecorator):

public abstract class CoffeeDecorator : ICoffee
{
    protected ICoffee _coffee;

    public CoffeeDecorator(ICoffee coffee)
    {
        _coffee = coffee;
    }

    public virtual int Cost()
    {
        return _coffee.Cost();
    }
}

The decorator, an abstract class, wraps around the components. It extends the `ICoffee` interface and holds a reference to a `Coffee` object, allowing it to modify or extend its behaviour.


Concrete Decorators (MilkDecorator, SugarDecorator)


public class MilkDecorator : CoffeeDecorator
{
    public MilkDecorator(ICoffee coffee) : base(coffee) { }

    public override int Cost()
    {
        return _coffee.Cost() + 5;
    }
}

public class SugarDecorator : CoffeeDecorator
{
    public SugarDecorator(ICoffee coffee) : base(coffee) { }

    public override int Cost()
    {
        return _coffee.Cost() + 2;
    }
}

Concrete decorators extend the abstract decorator, introducing specific modifications to the base component's behaviour.


Brewing Code Magic

Now, let's see this pattern in action:

ICoffee coffee = new SimpleCoffee();
Console.WriteLine("Cost of Simple Coffee: " + coffee.Cost());

ICoffee milkCoffee = new MilkDecorator(coffee);
Console.WriteLine("Cost of Coffee with Milk: " + milkCoffee.Cost());

ICoffee sugarMilkCoffee = new SugarDecorator(milkCoffee);
Console.WriteLine("Cost of Coffee with Milk and Sugar: " + sugarMilkCoffee.Cost());

Here, we create a simple coffee, decorate it with milk, and further enhance it with sugar. Each decorator seamlessly adds its unique flavour to the base component, showcasing the power and flexibility of the Decorator Pattern.



Conclusion: Sip, Sip, Hooray for Code Elegance!


As we conclude our exploration of the Decorator Pattern, let's raise our virtual coffee mugs to the beauty of elegant code design. With decorators gracefully wrapping and extending the behaviour of our components, we've learned how to achieve flexibility without sacrificing simplicity.


So, whether you're crafting software solutions or your favourite cup of coffee, remember the Decorator Pattern – a delightful recipe for code elegance.

9,444 views3 comments

3 комментария

Оценка: 0 из 5 звезд.
Еще нет оценок

Добавить рейтинг
Гость
22 нояб. 2023 г.
Оценка: 5 из 5 звезд.

🤗

Лайк

Гость
20 нояб. 2023 г.
Оценка: 5 из 5 звезд.

Good

Лайк

Гость
20 нояб. 2023 г.
Оценка: 5 из 5 звезд.

Nicely written

Лайк
bottom of page