Design Patterns and You: The Decorator

So, I’ve been doing some work on my Framework for Package API-Based ADF BC (locking doesn’t work as-is, and it turns out the framework needs some pretty significant re-architecture to get it to), and between that and my regular work, I’ve been a little ADF’ed out. So for a couple of weeks or so, I’m going to do something I haven’t done a lot of in this blog, and post a bit about pure Java. This will, hopefully, contain techniques of interest to ADF developers, and I’m probably going to use some ADF-based examples, but I’m mostly going to be talking about “Java techniques that they don’t teach you in a 5-day Java class.”

While working on the new version of the Framework, I’ve run into some significant annoyances, by which I mean the sort of coding work that a monkey–or better yet, a tool–could do but is long and fiddly to do by hand. This isn’t something that will primarily bug your average ADF developer, but it’s a sufficiently common Java technique that it would be a useful add-on for any Java IDE, JDeveloper included. It’d be a neat project for my Copious Free Time, but for now I’m just going to throw it out there in case anyone’s interested: The automatic generation of a decorator. Even if you’re not interested in that, you might want to read this article, just to get a feel for an important design pattern.

What’s a decorator? I’m not talking about someone who comes over and rearranges your furniture, or even a weird crab. A “decorator” is a design pattern for object-oriented languages (such as Java), which allows you to incrementally add functionality to a wide range of objects. A decorator usually has the following features:

  • It implements (or extends) an interface or high-level abstract class
  • It has a constructor that accepts an instance of that same interface or abstract class, which we’ll call the decoratee.
  • It delegates most of its functionality to its decoratee, but might do a little pre- or post- processing for certain methods.

A Simple Decorator Example

In case that’s a bit abstract for you, here’s a simple example. Say you have an interface like the following:

public interface Animal {
   public void eat(Food food);
   public Object excrete();
   public void move(double x, double y, double z);
   public Animal reproduce();
}

You don’t know, or care, anything about the implementation of a particular Animal. But what you do wish is that, whenever an animal eats or moves, you got some kind of notification about what it ate or how far it moved, and suppose most implementations of Animal don’t tell you that. You can get this information by using a decorator.

public class CommunicativeAnimal implements Animal {
  private Animal _decoratee;
  public CommunicativeAnimal(Animal decoratee) {
    _decoratee = decoratee;
  }

  public void eat(Food food) {
    _decoratee.eat(food);
    System.out.println("Ate: " + food);
  }

  public Object excrete() {
    return _decoratee.excrete();
  }

  public void move(double x, double y, double z) {
    _decoratee.move(x, y, z);
    System.out.println("Moved: " + Math.sqrt(x*x + y*y + z*z));
  }

  public Animal reproduce() {
    return _decoratee.reproduce();
  }
}

Now, all you need to do is ensure that, whenever you’re given an animal, you wrap it in a CommunicativeAnimal, and you’ll always see this information printed to your console. So instead of calling:

talkTo(ZooKeeper.getInstance().findAnimal("lion"));

You’ll call:

talkTo(new CommunicativeAnimal(ZooKeeper.getInstance().findAnimal("lion")));

This way, if the lion eats or moves during the execution of talkTo(), you’ll get the information printed to your console. Note that you don’t have to know anything here about how lions are implemented; ZooKeeper could be a class from a library for which you don’t have source code, and for all you could care, a ZooKeeper’s findAnimal() method might return some bizarre anonymous inner class, so long as that class implements Animal. Your decorator will still work. You can also compose decorators: For example, if you have another Animal decorator that, say, prints out timing information about an Animal’s activities, you could do the following to get a timed, communicative version of that lion:

talkTo(new TimedAnimal(new CommunicativeAnimal(ZooKeeper.getInstance().findAnimal("lion"))));

As you might guess, this sort of thing might be very useful in a variety of contexts, which is why the Java libraries actually contain a number of these decorator classes, such as FilterInputStream and its myriad subclasses (which decorate InputStream), or the various (non-public) implementations returned by the Collections.synchronizedXXX(XXX) methods.

When It Gets Annoying

Now, lets suppose that, rather than needing to decorate the functionality of an Animal, you need to decorate the functionality of, say, an oracle.jdbc.OracleCallableStatement (ahem). OracleCallableStatement has, let’s see…about 450 methods, counting the ones it inherits from other interfaces. And for many of those methods, all you really want is something like the following (stmt is the decoratee here):

public InputStream getUnicodeStream(int parameterIndex) throws SQLException {
  return stmt.getUnicodeStream(parameterIndex);
}

public void registerOutParameter(int paramIndex, int sqlType, int scale, int maxLength) throws SQLException {
  stmt.registerOutParameter(paramIndex, sqlType, scale, maxLength);
}

That gets to be…a lot of typing. And notice that, while a good IDE (such as JDeveloper)’s “implement interface” functionality will generate all the method stubs for you, you still need to write every single method body. And most of them are trivial.

What the Extension Could Do

So here’s what I’d love to see an extension (especially a JDeveloper extension) do:

Generate an implementation of an interface, or a concrete subclass of an abstract class, with all of the following:

  • A private instance variable typed to the interface/abstract class (“decoratee”)
  • A constructor that takes an instance of the decoratee and assigns the instance variable to it
  • Implementations/overrides of all public methods to delegate to the decoratee, throwing any checked exceptions the decoratee method throws
  • For package interfaces (within the same package as the decorator), implementations of all package private methods to delegate to the decoratee, throwing any checked exceptions the decoratee method throws
  • For abstract classes, implementations/overrides of all accessible methods to delegate to the decoratee, throwing any checked exceptions the decoratee method throws

Of course, since you might want to decorate a class for which you don’t have the source code, this would have to be an option that allows you to specify anything on the classpath, rather than, say, a right-click menu on a Java source file in the Application Navigator.

Next week, I’m going to talk a bit about another design pattern I’ve found useful, and that I’d love a bit of tool help with implementing: The bridge, AKA the driver.

7 thoughts on “Design Patterns and You: The Decorator”

  1. Hi Jan,

    OK, that is pretty seriously cool, and makes me want to learn Groovy much better than I know it. I’d very much thought of its advantages as being that the script is a bit easier to write than Java, but the “meta-programming” described in that article makes it clear that it has some serious structural abilities. The ability to basically write a decorator-by-exception (that is, a decorator that just invokes most methods on the decoratee, but makes exceptions for particular methods) without having to implement every single one of the plain invocations, which is essentially what I would need, is pretty powerful. I’ll look into it.

    For those who don’t want to use Groovy, of course, I’d still think that the ability to generate a Java stub for the design pattern would be really nice. Lots of people (though not, I think, me) might find the cost of learning yet another technology–reasonably well, since this doesn’t look like it’d be in your standard 8-hour “Groovy for business logic” tutorial–too high for the advantages.

    Thanks much,
    Avrom

  2. Hie

    How would u like to be specifying the interface or abstract class name to generate the implementation class as per your needs?

  3. In a popup dialog, I’d imagine. Say, you’d select New | Design Patterns > Decoator. (Or something). You’d get a popup, much like the new Class dialog, except that in addition to specifying your standard class information, you could also specify a “decoratee”.

  4. Or, perhaps, you could have an “Implement Decorator” option on the Source and/or context menu, which would open a popup where all you do is specify the decoratee, and which would turn the current class into a decorator (by adding the one-argument constructor and field, and by adding basic delegators for any missing methods).

Leave a Reply

Your email address will not be published. Required fields are marked *