装饰器模式 - 添加未在接口中定义的功能

时间:2018-02-20 09:01:54

标签: java decorator

是否对此模式的使用有任何硬性规定,还是仅仅是为了在不使用继承的情况下在方法调用中实现其他功能?

我修改了下面的例子,我从SO帖子中提取了我正在考虑的内容。

 public interface Coffee {
     public double getCost();
     public String getIngredients();
 }
public class SimpleCoffee implements Coffee {
   @Override
   public double getCost() {
    return 1;
   }
   @Override
   public String getIngredients() {
    return "Coffee";
   }
}

 public class CoffeeDecorator implements Coffee {
   protected final Coffee decoratedCoffee;

   public CoffeeDecorator(Coffee c) {
    this.decoratedCoffee = c;
   }
   @Override
   public double getCost() { 
    //you can add  extra functionality here.
    return decoratedCoffee.getCost();
  }
   @Override
   public String getIngredients() {
    //you can add  extra functionality here.
    return decoratedCoffee.getIngredients();
   }

   public boolean methodNotDefinedInInterface() {
       //do something else
       return true;
   }
}

因此,考虑到上面的例子,它是否可行:

a)只要你认为合适,就可以使用简单的咖啡而不进行装饰

b)将未在Coffee界面中定义的其他功能添加到装饰器对象,例如methodNotDefinedInInterface()

有人还可以解释组合在这个模式中的位置,因为SimpleCoffee本身就可以存在,但它似乎是实际上“拥有”任何对象的装饰者。

虽然没有SimpleCoffee类(或Coffee的某些具体实现),但装饰器没有任何用途,因此聚合似乎不会发生在这里。

2 个答案:

答案 0 :(得分:1)

description of the pattern包括意图,它清楚地说明了模式的用途:

  

装饰器模式可用于静态地(或在某些情况下)在运行时扩展(装饰)某个对象的功能,而与同一类的其他实例无关,只要在设计时完成一些基础工作。 / p>

至于“硬性规则” - 我通常认为模式中根本没有“硬性规则”。就像,如果你没有像GoF描述的那样完全实现它,就不会有“模式警察”惩罚你。唯一的一点是,如果您遵循经典指南,其他开发人员在识别代码中的模式时会遇到更少的问题。

从我的角度来看,你的榜样非常好。

SimpleCoffee不是装饰者,所以没有任何作品。 CoffeeDecoratordecoratedCoffee作为一个组件(这里有你的作品)

答案 1 :(得分:1)

  

a)只要你认为合适,就可以使用简单的咖啡而不进行装饰

是的,当然。

  

b)添加咖啡中未定义的其他功能   接口到装饰器对象,如   methodNotDefinedInInterface()

您可以添加更多方法,就像向SimpleCoffee类添加新方法一样,但请注意,您需要在装饰器类的某处使用这些附加方法。

就个人而言,当有人给你一个Coffee的实例(即你没有实例化它)时,我觉得这个模式很有用。如果需要在运行时更改其行为,唯一的方法是将其包含在Coffee类型的另一个对象中。这是你可以将它扔进装饰器类的时候。装饰者可以在提供一些新行为的同时暴露一些原始行为。