Using Decorators to handle cross-cutting concerns
For my first article on Medium I decided to write about a very simple but powerful technique to reduce boiler-plate code. I was actually planning of posting this on my blog but I’m migrating the hosting in these days and I’m still waiting for the domain to point to the new DNS. Turns out it gave me the chance to try Medium instead :)
Cross-cutting concerns can lead to a lot of duplicated boiler-plate code. In this post we’ll explore a simple way to encapsulate them in reusable components using the Decorator pattern.
Let’s first talk a bit about “cross cutting concerns”. On Wikipedia we can find this definition:
Cross-cutting concerns are parts of a program that rely on or must affect many other parts of the system.
In a nutshell, they represent almost everything not completely tied to the domain of the application but that can affect in some way the behaviour of its components.
Examples can be:
- error handling
Instrumentation for instance can lead to a lot of boilerplate code which eventually will create clutter and pollute your codebase. You’ll basically end up with a lot of code like this:
Of course, being IT professionals, you can quickly come up with a decent solution, find the common denominator, extract the functionality, refactor and so on.
So…how would you do it? One option would be to use the Decorator pattern! It’s a very common pattern and quite easy to understand:
Basically you have a Foo class that you need somewhere that implements a well known interface, and you need to wrap it into some cross-cutting concern. All you have to do is:
- create a new container class implementing the same interface
- inject the “real” instance
- write your new logic where you need
- call the method on the inner instance
- sit back and enjoy!
Very handy. Of course it can be quite awkward in case your interface has a lot of methods, but in that case you might have to reconsider your architecture as it is probably breaking SRP.