Archive for January, 2007

The Decorator-Decorator Pattern

| January 19th, 2007

Among all the design patterns, the decorator pattern has always been super-useful to me. But recently, I came across a strange requirement which led me to modify the decorator pattern into something which I call the decorator-decorator pattern or simply the d2 pattern. The decorator pattern empowers programmers to write a wrapper over an object and make custom modifications to it, thus producing an entirely new object without actually having to create one from scratch. The flow of control in the decorator pattern can be summarized in the following diagram:

Decorator Pattern
Thus, the decorator pattern essentially has a one-way flow of control.

The Decorator-Decorator Pattern
Coming back to the absurd requirement I was talking about, I needed to implement a decorator pattern with a two-way flow of control, one from the Decorator II to Base and back, and the other from the Base to Decorator II and back. This can be summarized in the diagram below:
Decorator-Decorator Pattern
The Motivation
The motivation for such a pattern was derived from a requirement wherein the Base class had a number of decorators with the last decorator being a caching decorator. Every thing seemed fine as per the normal decorator pattern as the results from the Base class where successfully cached by the Caching decorator. But the problem arose when the Base class had to interact with the Caching decorator. This was not possible with the decorator pattern as it allowed only a single flow of control.

The Solution
There are a number of solutions to solving this problem. For instance, the cache can be decoupled into a caching API and then hooked within the Base class. But if that is not feasible, then we need to modify the decorator pattern to somehow support a two-way flow of control. This can be achieved by fusing together one decorator pattern with another inverted decorator pattern.This can be understood by the following code:

DownInterface.java: This interface defines the functions to be decorated as per the usual decorator pattern.

public interface DownInterface {

// The function to be decorated downwards
public void howYouDoinDownThere();

// The function to set the parent decorator
public void setParent(UpInterface ui);
}

UpInterface.java: This interface defines the functions to be decorated as per the inverted decorator pattern.

public interface UpInterface {

// The function to be decorated upwards
public void howYouDoinUpThere();

}

BaseClass.java: The object to be decorated.

public class BaseClass implements DownInterface, UpInterface {

// The UpInterface Object
UpInterface upInt;

public BaseClass() {
}

// Set the decorator parent which can be used in the inverted decorator pattern
public void setParent(UpInterface upInt) {
this.upInt = upInt;
}

public void howYouDoinDownThere() {
System.out.println(“howYouDoinDownThere in the BaseClass”);
}

public void howYouDoinUpThere() {
System.out.println(“howYouDoinUpThere in the BaseClass”);

// Call the howYouDoinUpThere of the parent decorator
upInt.howYouDoinUpThere();
}
}

DecoratorI.java: The decorator.

public class DecoratorI implements DownInterface, UpInterface {

// The DownInterface Object
DownInterface downInt;

// The UpInterface Object
UpInterface upInt;

public DecoratorI(DownInterface downInt) {
this.downInt = downInt;

// Set the parent of the class being decorated as THIS class itself
downInt.setParent(this);
}

public void setParent(UpInterface upInt) {
// Do nothing
}

public void howYouDoinDownThere() {
System.out.println(“howYouDoinDownThere in the DecoratorI”);

// Call the howYouDoinDownThere of the object being decorated
downInt.howYouDoinDownThere();
}

public void howYouDoinUpThere() {
System.out.println(“howYouDoinUpThere in the DecoratorI”);
}
}

As seen above there are two interfaces, one to define the downward flow of control and the other to define the upward flow of control. The regular decorator pattern is implemented using the DownInterface and the inverted decorator pattern using the UpInterface. To make these two work in unison, the setParent function is defined in the DownInterface which allows the object being decorated to save a reference of its decorator, which can in turn be used for the inverted decorator pattern. So now, a call to the howYouDoinDownThere function of DecoratorI is redirected to that of BaseClass causing it to be decorated by DecoratorI. And a call to the howYouDoinUpThere function of BaseClass inturn calls the howYouDoinUpThere of DecoratorI yielding it to decorated in an inverted manner.

Hence when the decorated object calls howYouDoinDownThere the output would look like:

howYouDoinDownThere in the DecoratorI
howYouDoinDownThere in the BaseClass

whereas when the BaseClass internally calls howYouDoinUpThere the output would look like:

howYouDoinUpThere in the BaseClass
howYouDoinUpThere in the DecoratorI

Thus, some really cool and interesting patterns can be derived by slightly modifying the existing ones. If you have invented any such derived patterns why don’t you share them with me?