News Ticker

Decorator Pattern

Decorator Pattern

The decorator pattern is one of the GoF Structural Pattern and dynamically adds logic to an object. Instead of inheritance, the decorator adds functionality at run time. They introduce a huge amount of flexibility.

I often post about design patterns on Twitter. Follow me here

In the classical implementation, both decorator and target object must implement the same interface. The decorator wraps the target object and adds its own behavior.

@Decorator
@Priority(Interceptor.Priority.APPLICATION)
public class PriceDiscountDecorator implements Product {

  @Coffee
  @Any
  @Delegate
  @Inject
  private Product product;

  public String generateLabel() {
    product.setPrice(product.getPrice() * 0.5);
    return product.generateLabel();
  }
}

The implementation of the pattern relies on the delegate and decorator implementing the same interface. The delegate is wrapped and specific logic implemented for each of the interface’s methods.

The CDI container injects any available instance of a concrete instance of the Product interface into the Product member variable.

When a call is made to the generateLabel method of any Product instance, the container intercepts it. The call is delegated to the generateLabel method of the PriceDiscountDecorator decorator, where it discounts the product’s price and passes the call onto the original destination by calling the generate Label method of the destination Product instants.

Annotate with a qualifier the class you wish to decorate and the instance variable in the decorator and only instances of those classes will be injected into the decorator.

The order in which the decorators are called is specified in an XML file or by setting an Interceptor priority. Lower priorities decorators are called first.

The Good, Bad and the Ugly

The Good

It is very easy to change the behavior without breaking legacy code.

The Bad

It may need XML configuration (<CDI 1.1) to define the order of applying the decorators.

The Ugly

As always overuse will introduce an execution flow which is hard to follow.

I often post about design patterns on Twitter. Follow me here

What Next?

Java EE has simplified many other patterns such as the Observer PatternSingleton PatternFacade Pattern and Factory Pattern.

Leave a Reply

%d bloggers like this: