'Head First Design Patterns: Decorator example IS-A and HAS-A confusion

Viewed 42

I'm trying to get my head around design patterns. I think they may be one step too advanced in my programming abilities as I am struggling quite a bit with them, however my university assignment is to apply them. So here I am.

I am going through the example of the Decorator Pattern from the Head First book. This is the example:

Head First Design Patterns: Decorator UML

As you can see in the diagram, the CondimentDecorator has the IS-A and HAS-A relationship with Beverage. However, here is the code they write for the CondimentDecorator and one of the condiments, Mocha:

CondimentsDecorator

Mocha

In the CondimentDecorator class the only thing that it contains is a method getDescription.

It's the Mocha class that contains instantiates the Beverage class AND calls getDescription.

So doesn't this mean that it's the Mocha class that has a IS-A and a HAS-A relationship?

1 Answers

The decorator pattern is indeed not easy to grasp when learning OOP: it uses inheritance and object composition together to offer something that looks like dynamic inheritance but is mostly based on composition. In addition, the example uses several levels of inheritance, which makes it even more complex to grasp.

The idea in this design, is twofold:

  • a Mocha is a CondimentDecorator that you can use it everywhere where a CondimentDecorator is expected. Moreover, since a CondimentDecorator is a Beverage, you can also use a Mocha everywhere where a Beverage is expected. This is the purpose of the inheritance in this design (IS-A).
  • a CondimentDecorator object (such as a particular Mocha) knows a Beverage object that it enriches with additional responsibilities, acting as intermediary: it deals a "front-end" to the external world, and enriches the behavior of the other objects by doing additional things in addition to forwarding calls. This is the purpose of the association which is implemented in a code with object composition (i.e. Beverage beverage) - (HAS-A, but this terminology might be misleading).

In consequence, we can observe the following:

  • The Mocha class inherits the HAS-A and the IS-A relationships from the CondimentDecorator. These inherited relationships are not added in the UML diagram.
  • The Mocha class has no additional HAS-A relationship
  • The Mocha class must implement its own getDescription() , since it inherits directly from the CondimentDecorator which makes it abstract, whereas the Beverage provides a default implementation.
  • An instance of Mocha, e.g. an object Mocha aMochaInCup2987662 = new Mocha(aHouseBlendInCup2987662); is itself at the same time a Beverage a CondimentDecorator and a Mocha and has internally all the features provided by the three classes even if they are not all visible/accessible.
Related