Decorating Envelopes
Sometimes Very often I need a class that implements an interface by making an instance of another class. Sound weird? Let me show you an example. There are many classes of that kind in the Takes Framework, and they all are named like *Wrap
. It’s a convenient design concept that, unfortunately, looks rather verbose in Java. It would be great to have something shorter, like in EO for example.
North by Northwest (1959) by Alfred Hitchcock
Take a look at RsHtml
from Takes Framework. Its design looks like this (a simplified version with only one primary constructor):
class RsHtml extends RsWrap { RsHtml(final String text) { super( new RsWithType( new RsWithStatus(text, 200), "text/html" ) ); } }
Now, let’s take a look at that RsWrap
it extends:
public class RsWrap implements Response { private final Response origin; public RsWrap(final Response res) { this.origin = res; } @Override public final Iterable<String> head() { return this.origin.head(); } @Override public final InputStream body() { return this.origin.body(); } }
As you see, this “decorator” doesn’t do anything except “just decorating.” It encapsulates another Response
and passes through all method calls.
If it’s not clear yet, I’ll explain the purpose of RsHtml
. Let’s say you have text and you want to create a Response
:
String text = // you have it already Response response = new RsWithType( new RsWithStatus(text, HttpURLConnection.HTTP_OK), "text/html" );
Instead of doing this composition of decorators over and over again in many places, you use RsHtml
:
String text = // you have it already Response response = new RsHtml(text);
It is very convenient, but that RsWrap
is very verbose. There are too many lines that don’t do anything special; they just forward all method calls to the encapsulated Response
.
How about we introduce a new concept, “decorators”, with a new keyword, decorates
:
class RsHtml decorates Response { RsHtml(final String text) { this( new RsWithType( new RsWithStatus(text, 200), "text/html" ) ) } }
Then, in order to create an object, we just call:
Response response = new RsHtml(text);
We don’t have any new methods in the decorators, just constructors. The only purpose for these guys is to create other objects and encapsulate them. They are not really full-purpose objects. They only help us create other objects.
That’s why I would call them “decorating envelopes.”
This idea may look very similar to the Factory design pattern, but it doesn’t have static methods, which we are trying to avoid in object-oriented programming.
You may also find these related posts interesting: Composable Decorators vs. Imperative Utility Methods; Defensive Programming via Validating Decorators; If-Then-Else Is a Code Smell; Vertical and Horizontal Decorating; Why InputStream Design Is Wrong;
Reference: | Decorating Envelopes from our JCG partner Yegor Bugayenko at the About Programming blog. |
You should check out kotlin. It has a delegation keyword that pretty much does exactly what you’re asking for. Despite all the other really awesome things in the language, that’s probably my favorite because it makes my favorite pattern (decorator) much easier to do.
It’s a JVM language thats highly interoperable with Java, so you wouldn’t have to sacrifice too much to get the ability.