Real Life Example of Decorator
Imagine you have bought a Car. It’s a nice car — you generally happy with it. But suddenly you realised — “Man, boot is NOT big enough!” and there is a particular ride or two, where you need extra space for additional luggage.
You may consider buying or rent a Trailer, to extend current capacity of your car. In general, it will be exactly the same car, and if you need, you can use it without the Trailer. But when you do need extra boot space you can use it with the Trailer.
In the Car with small boot analogy, the Trailer is acting as a Decorator — It changes our car abilities, without changing car itself
Problem to solve
In programming we may face similar challenges, like we had with the Car in our story above. Imagine, you have a User Object. It’s solid well designed and is used across multiple areas of your application.
Adding any extra logic on top of it, will affect entire application and all use cases. It will be even more annoying if you only need couple of tweaks for one or two unique scenarios.
In order to keep your initial Objects or Components untouched you can implement Decorator Pattern concept to extend their functionality
Decorator Pattern is categorised as Structural. Which means its core concepts lays in assembling Objects into larger structures while keeping these structures flexible and efficient as well as not impacting original definition.
In general, if you drop all the dry parts of it, Decorator Pattern is designed to provide you with a clean way of extending abilities of your original Object or Component, without impacting its initial state or structure.
Decorator Pattern — simple diagram
First diagram is an example of codebase without Decorator being used, when requirements for additional features appeared for a specific use case.
With coloured shapes we represent Objects or Components. With Light Grey we represent use cases of these instances. With Dark Grey Shapes we show, extra features/logic, which has been added. And finally, with Dark Grey Branches we represent couple of use cases of these special features.
Second diagram show how quickly situation changes when we implement Decorator Design Pattern. We have nicely decoupled implementation of extra functions from main structures. Which gives us cleaner codebase, where we have kept original Objects or Components as they were designed initially.
Decorator Pattern — code example
Lets imagine we have following User Object.
Bear in mind this is extremely simplified example and is designed just to give you an insight of the general concept.
Now consider following scenario. You need Full Name to be prefixed with person title. You may think — “ok, in this simple example I can just prefix my
getFullName() output with value from
This approach is very easy to implement — looks attractive. Though, there are few downsides to this solution. First of all, you never know, if
title property may change, for example to
title property may be used for something else or removed.
This approach is also quite dirty from clean code point of view. Every time you need Full Name with the Title, you will be putting this hacky solution.
Another idea which may appear in your mind is — “ok, I will just add extra method to my User Object which returns Full Name prefixed with title”. Imagine this scenario at scale of a big project. Where you deal with already big and nicely designed Objects and Components.
If you will be adding extra functionality to each implementation every time you need to satisfy new requirement, you will blow your original structures to an enormous size. And most likely you will break the first SOLID rule — Single Responsibility.
That’s right, it’s time to introduce Decorator Pattern.
Code sample above represents entry point for User Decorators. You can think of it as an
index Decorator. The reason behind is that we might have multiple decorators, doing different things. In order to inject original User Object with the right methods and properties we need an entry Decorator to extend with more concrete Decorators.
There has to be Front Decorator aka index, which follows original object interface and acts as a parent for Concrete Decorators
Like in our simple example — prefix Full Name with the Title.
In this Concrete Decorator we are overriding original
getFullName() method with extra logic we need, but we are not impacting original structure.
Now let see how usage of all this beauty will look like.
I hope you have got the idea. The concept of Decorator is fairly easy. Harder will be to identify at first when to implement it in the real project. I hope this article gave you some glimpses of how and when you can use Decorator Design Pattern.
Thank you for taking time and reading this article. I really hope, you have gained some good insights and became even better engineer.
Have a great time, do things you love and see you in the next post. 🔥
A note from the Plain English team
Did you know that we have four publications and a YouTube channel? You can find all of this from our homepage at plainenglish.io — show some love by giving our publications a follow and subscribing to our YouTube channel!