QR code

Decorating Envelopes

  • Lviv, Ukraine
  • comments

Javajava OOPoop

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
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.

sixnines availability badge   GitHub stars