Java Design Patterns – Decorator Pattern in Head First Design Patterns

design-patternsjava

I'm trying to teach myself some design patterns using a book that I was recommended, Head First Design Patterns. I came to the chapter on the Decorator Pattern, and although I understand the purpose of it, I'm a bit fuzzy on it's layout.

Here is their basic UML of the Decorator pattern:
Imgur
(Sorry for the link, but SE won't let me upload a photo here for some reason)

Here is how they wrote out the code:

public abstract class Component {
    String description = "Unknown Description";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

public class ConcreteComponent extends Component {
    public ConcreteComponent() {
        description = "I am a concrete component";
    }

    public double cost() {
        return 1.99;
    }
}

public abstract class Decorator extends Component {
    public abstract String getDescription();
}

public class ConcreteDecorator extends Decorator {
    Component component;

    public ConcreteDecorator(Component component) {
        this.component = component;
    }

    public String getDescription() {
        return component.getDescription() + " with a decorator";
    }

    public double cost() {
        return .20 + component.cost();
    }
}

My question is, what is the need for a Decorator class in this situation? Why not leave getDescription() abstract and let ConcreteComponents and ConcreteDecorators implement it the way they need?

As a follow up, are there actual benefits to creating a Decorator class? This example doesn't seem to cover why it's useful or how it could be useful.

Best Answer

With a Decorator you are able to augment the code you are wrapping without changing it at all. And in some cases, not even having to know what it does.

The Open/Closed Principle states that

software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification

So, if you just made it abstract, what would happen if you had to then modify the description in your concrete implementation? You would have to modify your class.

Yes, this particular example is a little contrived. But, with this pattern, you can add decorators that augment a message (like in the design of Streams), or provide aspects that are orthogonal to the process (like logging or tracing) without touching or changing the code that the Decorator is wrapping.

Also, because a Decorator is a Component you can add a second Decorator without having to know that it wrapping a Decorator. In other words, this helps keep the Decorators separate from each other. This leads to code that is both decoupled and cohesive.