Design Patterns: Decorator
Tags: programming, designpatterns, decorator, csharp
Published: 2021-04-09 17:10:45

---
title: Design Patterns: Decorator
published: true
date: 2021-04-09 15:00:00 UTC
tags: programming,designpatterns,decorator,csharp
canonical_url: https://blog.kritner.com/2020/12/24/design-patterns-decorator/
cover_image: https://blog.kritner.com/2020/12/24/design-patterns-decorator/cover.jpg
series: Design Patterns
---

The decorator pattern is a structural design pattern that can be used to add functionality to classes without modifying the original class or its interface.

# The Decorator Pattern

From [Wikipedia](https://en.wikipedia.org/wiki/Decorator_pattern):

> In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern. The decorator pattern is structurally nearly identical to the chain of responsibility pattern, the difference being that in a chain of responsibility, exactly one of the classes handles the request, while for the decorator, all classes handle the request.

“Prefer composition over inheritance” might be something you’ve heard of before, and I feel like the decorator pattern is basically the epitome of this saying. Decorators are themselves implementations of an abstraction, that also depend on the abstraction itself. This allows for “composable” pieces of behavior in that you would likely have a single “main” implementation of an abstraction, then separate “decorator” implementations that build on top of it.

I’m not sure if that made sense, so hopefully an example will help clear things up.

# Implementing the decorator pattern

## The abstraction

For our abstraction, we’re going to create a service that retrieves the weather for us:

```cs
public interface IWeatherGettinator
{
    Task<Weather> GetWeather();
}

public class Weather
{
    public Guid Id { get; }
    public int FreedomUnits { get; set; }
    public bool ItGonRain { get; set; }

    public Weather()
    {
        Id = Guid.NewGuid();
    }
    
    public override string ToString()
    {
        var sb = new StringBuilder()
            .AppendLine("The current weather:")
            .AppendLine($"\tId: {Id}")
            .AppendLine($"\tTemperature (in freedom units): {FreedomUnits}")
            .AppendLine($"\tIt gon rain? {ItGonRain}");

        return sb.ToString();
    }
}
```

In the above, we have an interface `IWeatherGettinator` that has a single method, which takes no arguments, and returns the weather; simple enough.

## The base implementation

For this example, we’re going to pretend that to get the weather is an expensive operation, just because it makes one of the decorators of `IWeatherGettinator` more interesting and easier to see the point of it all (IMO).

So for the implementation of the `IWeatherGettinator`:

```cs
public class WeatherGettinator : IWeatherGettinator
{

    private readonly Random _random;

    public WeatherGettinator(Random random)
    {
        _random = random;
    }

    /// <summary>
    /// Gets the weather, mimics a long running task.
    /// </summary>
    /// <returns><see cref="Task"/> of <see cref="Weather"/></returns>
    public async Task<Weather> GetWeather()
    {
        await Task.Delay(5000);
        
        return new Weather()
        {
            FreedomUnits = _random.Next(0, 100),
            ItGonRain = _random.Next(0, 1) == 1
        };
    }
}
```

On getting the weather (which is a ~5 second operation), we get a random temperature and a value that indicates if it’s going to rain or not. Each time `GetWeather` is invoked, it takes another 5 seconds to retrieve a random “weather” instance.

The above implementation should look something like this when you `ToString` the retrieved `Weather` via a `GetWeather` invoke:

![Weather Gettinator Output](https://blog.kritner.com/2020/12/24/design-patterns-decorator/weatherGettinator.JPG)

## Our first decorator

Getting the weather seems to take a pretty long time! Perhaps we can introduce our first decorator to get some timing information on the implementation of `IWeatherGettinator`:

```cs
public class StopWatchDecoratorWeather : IWeatherGettinator
{
    private readonly IWeatherGettinator _weatherGettinator;

    public StopWatchDecoratorWeather(IWeatherGettinator weatherGettinator)
    {
        _weatherGettinator = weatherGettinator;
    }

    public async Task<Weather> GetWeather()
    {
        Stopwatch sw = Stopwatch.StartNew();
        var weather = await _weatherGettinator.GetWeather();
        sw.Stop();
        
        Console.WriteLine($"Decorated IWeatherGettinator ran for {sw.ElapsedMilliseconds}ms");
        return weather;
    }
}
```

This might look a little strange, so let’s go over it a bit. The `StopWatchDecoratorWeather` is an implementation of `IWeatherGettinator` that also _depends_ on an implementation of `IWeatherGettinator`. You can see that the method implementation `GetWeather` starts a stop watch, calls the injected implementation of `IWeatherGettinator`, stops the stopwatch, and writes to the console the length of time the operation took.

Now you probably wouldn’t actually write a decorator exactly like the above, but you could do something _like_ it, especially if you were to make use of a logging framework. Logging the above could make more sense, especially if the invoke took more than a certain amount of time.

How does the above get used? Well, you could “compose” your object like so:

```cs
IWeatherGettinator weatherGettinator = new StopWatchDecoratorWeather(new WeatherGettinator(new Random()));
```

You would actually want to be constructing these objects via an IOC container or something similar, this was to just get the point across… also there is some complexity to registering decorated objects with at least the .net core built in IOC container; though you could also use a [factory](https://dev.to/kritner/design-patterns-factory-4414) to accomplish it more easily.

What does the above construction mean? Well, we’re instantiating a new instance of a `StopWatchDecoratorWeather` which itself depends on a `IWeatherGettinator` instance, in this case we’re passing in a concrete implementation of `WeatherGettinator`.

Running the `IWeatherGettinator` while making use of the `StopWatchDecoratorWeather` would look like this:

![StopWatchDecoratorWeather Output](https://blog.kritner.com/2020/12/24/design-patterns-decorator/stopWatchDecoratorWeather.JPG)

## The issue with inheritance

Inheritance has an issue; an issue that can be solved through composition. I’ve mentioned this several times now, but it’s kind of hard (at least for me) to convey what I mean.

Say we wanted to introduce _another_ piece of functionality; in this post we’re going to be doing it through the use of decorators, but just imagine for a moment that we weren’t.

In c# a class can only ever extend a single other class. If we ever wanted to “mix and match” behaviors of an abstraction that relied on inheritance, that can be extremely difficult to do. If we have an interface `IFoo`, with an implementation `Foo`, then had separate implementations `A` and `B`, both of which extended `Foo`, how would we go about introducing yet another implementation `C`, that needed some of its own unique characteristics, as well as the additional functionality provided by both `A` and `B`? This would be challenging with an inheritance scenario, but is really trivial when making use of decorators.

To demonstrate that, let’s introduce another decorator to our `IWeatherGettinator`.

## The second decorator

We’ve done some testing with our `StopWatchDecoratorWeather` and determined that we could save a lot of time getting the weather if we introduced some caching. Thankfully, introducing caching via a decorator is very simple, and should look pretty similar to our first decorator!

```cs
public class CachedWeatherGettinator : IWeatherGettinator
{
    private readonly IWeatherGettinator _weatherGettinator;

    private Weather _cachedWeather;
    private DateTime _cachedOn;
    
    public CachedWeatherGettinator(IWeatherGettinator weatherGettinator)
    {
        _weatherGettinator = weatherGettinator;
    }

    public async Task<Weather> GetWeather()
    {
        var now = DateTime.Now; // this should be injected for testability, but we're demonstrating a decorator so...
        var timeDiffSecondsSinceCachedValue = now.Subtract(_cachedOn).TotalSeconds;
        
        if (_cachedWeather == null || timeDiffSecondsSinceCachedValue > 30)
        {
            Console.WriteLine("Cached value does not exist or is expired, get a new one.");
            _cachedOn = now;
            _cachedWeather = await _weatherGettinator.GetWeather();
        }
        else
        {
            Console.WriteLine("Using cached value...");
        }

        return _cachedWeather;
    }
}
```

In our new `CachedWeatherGettinator`, we’re making use of some instance state to return the previously retrieved weather if it’s less than 30 seconds since it was retrieved. You’ll notice this implementation, like our first decorator, both implements _and_ depends on `IWeatherGettinator`.

We can now try out our new decorator like this:

```cs
IWeatherGettinator weatherGettinator = new CachedWeatherGettinator(new WeatherGettinator(new Random()));
```

And you’ll see that the “first” call to the `IWeatherGettinator` will take the 5 seconds, but another call made immediately after will return much faster.

But even _more_ interesting that that, is we can make use of _multiple_ decorators for the same abstraction, the construction of which is considered composition.

What could that look like?

```cs
IWeatherGettinator weatherGettinator = new StopWatchDecoratorWeather(new CachedWeatherGettinator(new WeatherGettinator(random)));
```

We’re “composing” our object by decorating our base `WeatherGettinator` with multiple decorators! We have decorated the base object with both a `StopWatch` as well as `Caching` layer, mostly to demonstrate that the caching layer is in fact working. Let’s take a look!

![StopWatch and Caching Decoration](https://blog.kritner.com/2020/12/24/design-patterns-decorator/cachedWeatherGettinator.JPG)

# Reasons to use this pattern

Hopefully it should be pretty clear after going through the post why this pattern can be quite powerful, but just to reiterate:

- Adding additional functionality to an abstraction without changing the abstraction or its concretions.
- Keeping concerns of caching or logging separate from the base implementation. These are taken care of via decorators, allowing your core “business logic” to stay pure, and uncaring about the functionality provided by the decorators.

# References

- [Wikipedia: The Decorator Pattern](https://en.wikipedia.org/wiki/Decorator_pattern)
- [The Decorator Pattern Code](https://github.com/Kritner-Blogs/Kritner.PatternExamples/pull/2)
- [My other posts on Design Patterns](https://blog.kritner.com/categories/design-patterns/)
- Photo by [thetechnomaid](https://unsplash.com/photos/Y_vfj8HV7GU) on [Unsplash](https://unsplash.com/).