What is the decorator design pattern?
And how can you use this pattern in your Ruby projects?
The decorator design pattern helps you enhance an object by adding new capabilities to it without having to change the class.
Let’s look at an example!
Logging & Performance
In this example we are making HTTP requests using a gem like rest-client.
Here’s what that looks like:
require 'restclient' data = RestClient.get("www.rubyguides.com")
Now:
Let’s say that we want to add logging to some of our requests, and we don’t want to change the RestClient
module.
We can do this using the decorator pattern.
Here’s our logging module:
module LogHTTPRequest def get(url) puts "Sending Request For #{url}" super end end
This will print the information we want on the screen then call the original get
method from RestClient
.
To add logging capabilities to a request you can use the extend
method.
Like this:
class HTTPClient def initialize(client = RestClient) @client = client end def get(*args) @client.get(*args) end end client = HTTPClient.new client.extend(LogHTTPRequest) client.get("rubyguides.com")
You have to create this HTTPClient
wrapper class because RestClient
is a module & you can’t create objects from modules.
When To Use The Decorator Pattern
The beauty of this pattern is that you are only enhancing one object, so you could have a non-logging client & a logging client.
Another benefit is that you can layer these decorators & have one that does performance testing, another for logging, etc.
Combining decorators would not be possible if you used inheritance to create a HTTPClientWithLogging
, and a HTTPClientWithPerformanceTesting
class.
You can’t have WithLogging
and WithPerformanceTesting
at the same time unless you create this class…
class HTTPClientWithLoggingAndPerformanceTesting # ... end
The decorator pattern solves this problem while avoiding code duplication & crazy class names.
Video
[responsive_video type=’youtube’ hide_related=’0′ hide_logo=’0′ hide_controls=’0′ hide_title=’0′ hide_fullscreen=’0′ autoplay=’0′]https://www.youtube.com/watch?v=J_T5Gmr8Wrg[/responsive_video]
Summary
You have learned about the decorator design pattern, this pattern helps you add new capabilities to objects without having to change the class.
Don’t be passive! Now it’s your turn to practice & apply this concept yourself. It will help you remember this when you need it.
Share this article so more people can read it 🙂
You need to remove self
Yes, you are correct!
I was testing a different version of this code & I forgot to remove the self 🙂
Thank you.