The Decorator Pattern is not only a common one, but it is also one of the best ways to embrace object-oriented design. This approach is a form of “helper,” and the idea of a decoration fits it perfectly. It is an addition to a class without being a part of the class. Let’s look at this useful pattern.
The Decorator Pattern Defined
As always, we will start with the “Gang of Four” intent to set the stage for our discussion.
“Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.”
As I mentioned, the idea of a decorator as a decoration or accessory for a class is an excellent analogy. The goal of a decorator is to add functionality to a class without impacting the hierarchy. Thus, you can add the functionality to the parent without forcing child classes to take that on as well. This pattern works for optional features as well as situations where a hierarchy is not well-suited for linear growth of complexity. Graphical objects make a good example. You can add a border or not, shadowing or not, an audio component or not, and similar decorations to an object.
Applying The Pattern
The critical piece of a decorator is to create a hook for it in the hierarchy. Therefore, the root (or at least the parent class) needs to provide a way to utilize a decorator. In interface is the best way to meet this requirement. Thus, you have an interface that decorators implement, a way to attach decorators to an object, and then a call structure that looks for and executes decorators.
As an example, let’s think of a person object that we want to use to print out personal data. The core class has a first name and last name. We then have a collection of attributes that implement the Attribute interface of “printOut.” We can add an Address decorator that implements that interface, then a Phone, and an Email, etc. This is a simple but powerful example when you see that your core class can essentially be extended at each level. I can create a child class of Person called Employee and utilize those decorators or not. Adding an address to a Person does not force me to carry that in the child objects.
Java, PHP, C#, etc.
Your implementation language will not change how to address this pattern. It is as simple as a class, a property that expects a specific interface, and then specify the interface. Thus, this is not only a useful pattern it can also be very lightweight.