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.

So decorators wrap a base class recursively, right? And have a single super class object which is at the "core" class.

Couldn't you just add an ArryList/LinkedList of decorations in the "core" class and achieve the same thing? This would avoid recursion (which is expensive), but allow the dynamic behavior of being able to "decorate" your classes.

Is this a different pattern or an alternative version of decorators or something else?

Ex:

Decorator

Beverage class
  getDescription(){blah}
  cost();

HouseBlend inherits from Beverage
  cost(){2.99}

CondimentDecorator inherits from Beverage
  Beverage bev;
  cost(){.19 + bev.cost}
  getDescription{blah}

VS

Other?

Beverage class
  getDescription(){blah}
  cost();

HouseBlend inherits from Beverage
  List<Beverage> condiments      
  cost(){2.99 + iterative condiments}

CondimentDecorator inherits from Beverage
  cost(){blah}
  getDescription{blah}

It seems like the decorator might be a little more flexible, but the other version would allow you to keep track of specific instances of items. Also, if you had espresso you could have a double shot, where with a pure decorator that would be hard.

share|improve this question
    
Your alternative is the composite pattern, isn't? –  Armando Jun 10 '11 at 5:52
add comment

2 Answers

The decorator doesn't use embedded objects, but dynamic dispatch, and that isn't very expensive. In fact, with modern JIT compiling, it is essentially free. And as Deckard pointed out, the entire point of Decorators is that you can introduce variants without recompiling the base class.

The trade-off you should be looking at is essentially this: to be a Decorator, your class must inherit from a specific other class, and in most languages you can't inherit twice, which limits your options. But changing the base class implies recompiling it and potentially destabilizing every other client of that class. Depending on how many there are, that may or may not be acceptable.

share|improve this answer
add comment

The reason the decorator pattern works the way it does is because it aims at allowing subclassing-style functionality at runtime instead of compiletime. This is relevant since your alternative requires modification of HouseBlend at compiletime. This is something that the decorator pattern was explicitly designed to avoid.

In my experience, the decorator pattern is typically used when you get a binary component that exposes Beverage and a bunch of subclasses (such as HouseBlend) that you cannot modify. In this case, the decorator enables you to still modify the way those subclasses behave in a transparent way.

If you have access to Beverage and/or HouseBlend and can modify and recompile them, a host of alternative design options become available, including the one you propose.

share|improve this answer
    
There is another good reason to use decorators. Since they can be applied at runtime, they can come in any order and number, and they can dynamically increase and decrease, which would be difficult to achieve at compile time. –  wolfgangsz Jun 10 '11 at 9:47
1  
@wolfgangsz If you can modify the code, you can just add behaviour to allow dynamic reordering, parameterization, etc. I do agree that that is a useful capability that decorator makes simple to implement, but it's strictly part of the point in my answer. –  Deckard Jun 10 '11 at 10:58
add comment

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.