Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

share|improve this question

1 Answer 1

up vote 2 down vote accepted

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.

share|improve this answer
    
Okay, so which class exactly is supposed to be closed to change? From what I can tell, if I want to modify the description, I will have to modify Component or ConcreteComponent depending on how I implement description. –  comscis Jan 1 at 23:51
    
But not if you want to augment it (or Decorate it). Correct? How about if you wanted to Log every time getDescription was called in order to record performance statistics. So, Decorator allows us to add something to the call without touching the original. –  Davin Tryon Jan 1 at 23:52
    
In your answer, you talked about modifying the description in concrete implementation. Could you explain what you mean? There are two concrete implementations from what I can tell. I also don't quite get why you would want another Decorator class... –  comscis Jan 1 at 23:57
    
In the example above, if the ConcreteComponent was already written, and you wanted to add " with a decorator" to the description, you would then be forced to modify the ConcreteComponent class. –  Davin Tryon Jan 1 at 23:59
    
There is nothing stopping you from using many decorators. This pattern allows you to also decorate ConcreteDecorator because it is also a Component. As for when you would want to do this, it depends on the system you are building. You might want to add a decorator that Logs, Encrypts, and then Deletes the description etc. –  Davin Tryon Jan 2 at 0:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.