Can someone please walk me through the differences between (as in benefits of) creating decorator classes using constructor injection of another class as opposed to class inheritance? In the examples I can think of, I might accomplish the same end goal in one of two ways but I suspect I am missing something fundamental.
3 Answers
The decorator pattern concerns composing an object. To be able to inherit the type of that object, it must obviously be inheritable. Not all types are designed for inheritance, i.e., meant to be base classes, even if they from a purely technical viewpoint can be inherited (which I consider a design flaw).
The raison d'ĂȘtre for the decorator pattern is to be able to modify the behavior of objects without modifying the objects themselves. By inheriting, you're essentially modifying the object itself and what you get then is regular behavioral change through polymorphism, meaning that you did not accomplish the same thing.
So, both decoration and inheritance has their uses. Use decoration when anyone of these is true
- you can not inherit (for example if the class is
sealed
in C#) - you should not inherit (the class is obviously not meant to be a base class)
- you want to change the behavior of one particular object many times (by wrapping it with decorators of different behavior)
Note that inheritance is the most powerful tool there is in the OO toolbox. With great power comes great responsibility and that's not always easy to cope with. I'd say: Always compose or aggregate. When that just cannot be done, inherit. If you can't inherit, try harder to compose or aggregate."

- 24,991
- 10
- 72
- 122
I would resume as follows:
When should you inherit?
When objects are from the same semantic hierarchy and represent an is-a relationship.
What does that means?
That a Cat
is-a Feline
, indeed a Feline
is-a Vertebrate
, and so on.
When should you decorate?
When objects do not represent a is-a relationship. But, yes, both Coffee
and Milk
can be on the same hierarchy. But if you were to sell Cappuccino
you would not say that a Coffee is-a Milk, instead you'd decorate it with Milk
.
Conclusion:
Is-a is different from has-a. One is a subtype, the other is part of a composition.
But, see this: https://stackoverflow.com/questions/1621344/head-first-design-patterns-decorator-pattern
A real world example would be to create a security container as a Decorator for your controllers or services in order to make ACL checks.

- 1
- 1

- 6,194
- 2
- 24
- 55
Another really good reason to decorate is that it gives you the option to decorate an interface instead of a class. Then you become quite loosely coupled, and can add the orthogonal decoration behavior to multiple implementations of the interface without writing more code.

- 3,635
- 1
- 23
- 24