Head First Design Patterns - Decorator Pattern using Starbuzz


I am going through the book Head First Design Patterns and am specifically looking at the Starbuzz example for the Decorator pattern.

I am having trouble understanding that what exactly is the need for CondimentDecorator in the example provided. Why can't Mocha simply extend Beverage? What's the need for another layer of abstraction?`

public abstract class Beverage { String description = "Unknown beverage"; public String getDescription() { return description; } public abstract double cost(); } public abstract class CondimentDecorator extends Beverage { public abstract String getDescription(); } public class Mocha extends CondimentDecorator { Beverage b; public Mocha(Beverage b) { this.b=b; } public String getDescription() { return b.getDescription() + ", Mocha"; } public double cost() { return .20 + b.cost(); } }


Well, in the sample you posted it isin't that clear, but the abstract class usually takes care of the component encapsulation and the default method implementations are to delegate method calls to that component.

Therefore, when implementing concrete decorators, you would't have to override all methods if you don't need to.


public abstract class CondimentDecorator extends Beverage { Beverage beverageToDecorate; public CondimentDecorator(Beverage beverageToDecorate) { this.beverageToDecorate = beverageToDecorate; } public String getDescription() { return beverageToDecorate.getDescription(); } public double cost() { return beverageToDecorate.cost(); } }



Why can't Mocha simply extend Beverage? What's the need for another layer of abstraction?


The problem is how to deal with the combinations. Mocha is only one variant, but what about Mocha + House Blend + Steam Milk, etc. There's a lovely image on p.81 of the design solution using only this "layer" which has so many classes inheriting from Beverage that it's a "maintenance nightmare."

The CondimentDecorator allows adding any number of combinations to your Beverage through <em>composition</em> rather than <em>inheritance</em>.


  • JPA Specification complex query
  • Java - Rome: I am trying to parse RSS feed but get a error on some channels
  • JSF: Empty nested dataTable
  • How can I alter the spacing for the Y-Axis Labels in MPAndroidchart?
  • nested c:foreach in jstl
  • update record in database using jdatabase
  • Java: java.util.ConcurrentModificationException
  • Boost binary serialization doesn't work occasionally. The parsed data is corrupted sometimes
  • What is the reason that Policy.getPolicy() is considered as it will retain a static reference to the
  • Appium MobileElement swipe returns unknown server error
  • Building Qt project for C++11 standard
  • Magento site down due to mysql error General error: 1030 Got error -1 from storage engine
  • How can the INSERT … ON CONFLICT (id) DO UPDATE… syntax be used with a sequence ID?
  • QLPreviewController hide print button in ios6
  • Projection media query: browser support and workarounds?
  • Uncaught Error: Could not find module `ember-load-initializers`
  • output of program is not same as passed argument
  • Incrementing object id automatically JS constructor (static method and variable)
  • Eraser for UIBezierPath
  • How to limit post in wp_query
  • Upload files with Ajax and Jquery
  • Build own AppleScript numerical error handling
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • AngularJs get employee from factory
  • Java static initializers and reflection
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • Change div Background jquery
  • apache spark aggregate function using min value
  • Bitwise OR returns boolean when one of operands is nil
  • unknown Exception android
  • Is there any way to bind data to data.frame by some index?
  • Django query for large number of relationships
  • Sorting a 2D array using the second column C++
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • Observable and ngFor in Angular 2
  • How can I use `wmic` in a Windows PE script?
  • failed to connect to specific WiFi in android programmatically
  • Unable to use reactive element in my shiny app
  • How to push additional view controllers onto NavigationController but keep the TabBar?
  • How can I use threading to 'tick' a timer to be accessed by other threads?