When to Use the Decorator Pattern in Development

0
6877

If you’re going to apply for a coding job for an object oriented language, there’s a chance that you’ll be asked about the decorator pattern.

Decorator Pattern Definition

So what exactly is the decorator pattern? A dead simple explanation of the decorator pattern is that it allows you to add functionality to a specific object instead of an entire class of objects.

When working with the decorator pattern you may feel like you’re using plain old object oriented inheritance. However there is a key difference. While inheritance typically is used when a class is a sub type of a parent class, decorators are used when we simply need to pass some custom behavior to a specific set of objects.

If this still seems a bit fuzzy, don’t worry, we’ll dive into an easy to understand code example.

Decorator Pattern Code Example

Classic Inheritance

decorator pattern

Before we get into decorators, let’s start by looking at classic object oriented inheritance. In this program we have two classes, a User class and an Admin class. The Admin class inherits from User and overrides the default greeting method.

decorator pattern

If we run this code everything works properly. New users have a greeting that says “welcome to the site” and admins are informed that they’re on the admin dashboard.

This code is setup properly because an Admin is a type of User. This is classic object oriented inheritance.

Using a Decorator

But what happens when we want to add some custom behavior to our User class, such as users that are on a trial membership?

Imagine that you have a site like Netflix where you give users the ability to sign up for a trial account. Technically we could create a new class called TrialUser and have it inherit from User. However a trial user isn’t really a type of user. It’s simply a stage where the user is at in the sign up process.

This is a good example of how we can use the decorator pattern and give custom behavior to users that are currently in the trial stage.

decorator pattern

In this Ruby code I’ve created a module called TrialUser. Inside of the module I’ve added a custom greeting method that returns a greeting specific to users on a trial membership.

From here I can create a new User just like I would normally. However, notice how I’m using the extend method and passing in the TrialUser module? This tells Ruby that slide the TrialUser module in as a layer of our new User object.

decorator pattern

From here I can call the greeting method and it will print out the custom greeting that we created for trial users.

Items to Notice

This is a great way to customize the behavior of objects without cluttering classes with unnecessary code. You should also notice a few other key items:

  • Our decorator is not affecting all users, only the specific user that it’s being layered on.
  • It’s also important to notice that our decorator has access to the instance variables set in the User class.

When to Use the Decorator Pattern?

So when is it a good idea to use the decorator pattern in a program?

There are a few scenarios where decorators are preferable over inheritance.

  1. In scenarios like our example where we need to customize an object that does not fit the is a test required for inheritance.
  2. Using decorators is considered a best practice when it comes to rendering view code. Instead of hard coding server side code inside of HTML files, decorators can be leveraged to streamline front end templates.
  3. Decorators are also popular if you work with streams in frameworks such as .NET.

Summary

I hope that this has been a helpful guide to understanding the decorator pattern. Decorators have been around for decades and have unique implementations in each language. The example I provided in this guide was one of four popular ways to implement decorators in Ruby. In the resources section of this guide I’ve linked to additional posts that you can check out to deepen your knowledge on the subject.

Resources

LEAVE A REPLY

Please enter your comment!
Please enter your name here