如何确保特定的装饰器类还没有装饰我的对象?

时间:2015-04-17 19:22:14

标签: java decorator

我有一个装饰器类,它基本上包裹着一个名为Drink(Coffee Drink)的类。您可以用浓咖啡,巧克力和焦糖来装饰您的饮料。我知道如何实现这个,我做了一个非常基本的装饰器实现。

我怎样才能改变我的奶油类,以确保它只能添加到饮料中一次?

public class WCream extends DrinkDecorator
{
   private final String TYPE = "Whipped Cream";
   private final double COST = 1.00;
   private Drink drink;


   public WCream(Drink d)
   {
      this.drink = d;  
   }

   public String getType()
   {
      return drink.getType() + ", " + TYPE;
   }

   public double cost()
   {
      return COST + drink.cost();
   }


}

这是我尝试使用Singleton使其工作的方式,这可以避免重复的生奶油,但它会跳过我添加的下一件事......所以如果我在生奶油后添加巧克力,它会赢得'加入巧克力。

然后,在我使用的测试者类中

myDrink = WCream.getUniqueInstance(myDrink); 
//instead of
myDrink = new WCream(myDrink);

这是我为其余装饰者做的方式。

public class WCream extends DrinkDecorator
{
   private final String TYPE = "Whipped Cream";
   private final double COST = 1.00;
   private Drink drink;

   private static Wcream uniqueInstance;


   public WCream(Drink d)
   {
      this.drink = d;  
   }

   public static WCream getUniqueInstance(Drink d)
   {
      if(uniqueInstance == null)
          uniqueInstance = new WCream(d)

      return uniqueInstance;
   }   

   public String getType()
   {
      return drink.getType() + ", " + TYPE;
   }

   public double cost()
   {
      return COST + drink.cost();
   }


}

1 个答案:

答案 0 :(得分:0)

可怕的答案:

使用String比较

在构造函数中验证它
  public WCream(Drink d) {
    if (d.getType().containsAll("WHIPPED CREAM") { 
       KABOOOM
    }
    this.drink = d;
  }

好一点:

提供一些返回装饰器或图层列表的方法:

 public List<Components> getComponents() {
    List<Components> list = new ArrayList<>();
    list.add(Component.WHIPPED_CREAM);
    list.addAll(this.drink.getComponents());
    return list;
 }

然后在构造函数中执行相同的验证,但现在只使用常规集合

   public WCream(Drink d) {
    if (d.getComponents().contains(Component.WHIPPED CREAM)) { 
       KABOOOM
    }
    this.drink = d;
  }

更好的回答,但这很大程度上取决于你想做什么:

提供某种类型的构建器,您可以根据需要配置它,并在某些时候将您的饮料与所有需要的装饰器组装在一起,它会让您难以创建对象协作并执行所需的验证