Head First Design Patterns - Decorator Pattern usi

2019-07-21 02:18发布

问题:

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();
   }
}

回答1:

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.

e.g.

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();
    }
} 


回答2:

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 composition rather than inheritance.