Archive for the Design Category

A great set of slides from Bryce Glass’s talk on Reputation System Designs at the IA Summit. Bryce Glass is a senior interaction designer on the Y! OS social team.

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?

Understanding Tacit Knowledge

| September 25th, 2006

I chanced upon an article by Jon Udell titled ‘The tacit dimension of tech support‘ which gave me an insight on tacit knowledge, knowledge that people use implicitly without even realizing it. Understanding this so called tacit knowledge will aid us in designing systems that are more intuitive and user friendly. Tacit knowledge is of two kinds, the first kind is knowing how to do things and the second, knowing how to find out how to do things.

Knowing How To Do Things

If I want to refine my search I know I can find the feature in something called the Advanced Search.

Knowing How To Find Out How To Do Things

If I want to refine my search at a particular site I can always Google about it.

Change Your Perspective

Determining the above knowledge for the target audience of your product could determine how sticky the users stay to your product. Usually while designing systems, the developers rely on their tacit knowledge which is not quite the same as that of the non-techie users. This particularly holds true to User Interface design. I have been part of many discussions on UI design for one of my projects. I have often argued on things like ‘we should have that link there and not here‘ because that seemed more reasonable to me. What I didn’t realize was that these arguments were based on my tacit knowledge and not that of a typical user.

Developers need to change their outlook and keep the above in mind the next time they go around designing systems.