by andrew

Design patterns: decorator

It is about time for next design pattern which I have learnt by reading the book I have already mentioned several times[1, 2] on this blog Let’s do not make this prelude too long and start with book examples of decorator pattern.

Book examples

This time we learn Starbuzz Coffee. They got really popular and their ordering systems can not handle updates well enough anymore. They have just used inheritance and a simple model. The abstract base class Beverage has four subclasses: HouseBlend, DarkRoast, Decaf and Espresso. Each of the subclasses has to implement their own cost() method. At first look this model makes sense. But then in reality people would like some additional condiments added to their coffee, don’t they? Starbuzz Coffe must include it into their ordering system and doing that with the inheritance model looks like a nightmare.

Overused inheritance in Starbuzz Coffe.

Another idea was to move condiments to the base class, add setter and getter methods and implement cost() methods in the way they check if a beverage is being served with or without a condiment. Of course it is a bad idea again. It decreases number of classes in our codebase but every time if there is a change we need to implement it in the existing code. At this point in the book we learn how decorator pattern works.

The Decorator Pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

It might not tell enough. Maybe a look at pseudo-UML diagram will be helpful:

Starbuzz example of usage of decorator pattern

The abstract decorator class CondimentDecorator inherit from the base abstract class mostly to achieve type matching but not to get behavior. A decorator has to match type with an object it is going to decorate. We are explained also that we could have used here interface to match types but as the code had already base abstract class there was not need to alter existing code.

The few code snippets should help understand everything more deeply. Similar to previous posts, I have written PHP version of the code attached to the book.

Espresso is a regular beverage which we decorate with whip. The total cost is a result of calling cost() method on Whip decorator. The decorator delegates the task to decorated object and returns sum of its and Espresso costs.

Other examples

Except this nice coffee making scenario example (which can be found on Wikipedia as well) authors in the book mentions also Java I/O package where you can find lots of decorators. You can read about abstract component InputStream, abstract decorator FilterInputStream and different subclasses of InputStream and of FilterInputStream. You can decorate FileInputStream with BufferedInputStream and decorate it as well with LineNumberInputStream.

As it goes for PHP I did not find any built-in features. But there are lots of examples of using decorator pattern. You can use it to build HTML forms, to build useful classes which helps in flexible way operate on Strings or you can decorate existing validators of a form.

I remembered that when I used Symfony 1.4 I read about decorator pattern first time. It was used there to manage templating system. Symfony 2 strongly encourage to use Twig templating library and its inheritance in templates (which at the end is decorator pattern).