Decorator模式链方法如何调用?

时间:2017-02-13 14:59:05

标签: java oop inheritance design-patterns polymorphism

我读了一个Decorator设计模式的例子。我知道这种设计模式动态地修改了一个特定实例的行为。我在下面给出的例子也是可以理解的。我不明白的一点是,当我在牛奶对象上调用c.getCost()时,它返回1.5。 只有Simplecoffee的{​​{1}}返回1,但牛奶返回1.5时getCost()从哪里返回?

任何人都可以解释c.getCost类和Milk类之间的链接,以及在使用milk对象调用时如何执行方法Simplecoffee的流程? getCost()方法如何返回1.5?

getCost()

4 个答案:

答案 0 :(得分:5)

  

getCost()方法如何返回1.5?

getCost()中的Milk方法首先调用getCost上的decoratedcoffee方法,该方法是SimpleCoffee的引用。因此,这将从getCost调用SimpleCoffee方法,该方法返回1(读取:运行时多态性)。接下来,getCost中的Milk方法会将此调用的返回值(即1)添加到0.5,从而将结果显示为1.5

这是 Decorator 模式的重点。 Decorator 用于通过将新对象包装到现有链中来创建方法调用链。

答案 1 :(得分:1)

我宁愿将您的Milk类命名为MilkedCoffee。装饰器通过包装它为原始对象添加更多功能,同时属于原始对象的同一接口,这样您的客户端代码就可以在不知道它是咖啡(原始类)还是milkedcoffee(装饰器)或冰咖啡(另一个装饰)。所以你的例子中的装饰咖啡应该是咖啡,而不是添加到牛奶,糖等咖啡中。等等

要回答您的原始问题,如果您的逻辑是在咖啡加牛奶时加上.5成本(换句话说装饰为MilkedCoffee),则返回值1.5看起来很好。

答案 2 :(得分:1)

让我们看一下并理解这段代码:

coffee c = new simplecoffee();
System.out.println("Cost:" + c.getCost());
  • 创建 simplecoffee 对象并将其分配给c
  • c声明要输入咖啡(没问题,因为 simplecoffee 咖啡界面的实现)。

下一步:

c = new milk(c);
System.out.println("Cost:" + c.getCost());
  • 创建牛奶对象,并将c分配给新的牛奶对象(覆盖旧值c)。
  • 牛奶扩展了一个抽象类coffeedecorator,它还实现了咖啡接口。
  • 上面的 simplecoffee 对象被分配到 milk 类中的实例变量。

考虑在最后一次打印之前调用的 milk.getCost()的实现:

    public double getCost(){

       return super.getCost() + 0.5;
    }
  • super.getCost()已在 coffeedecorator 类中实施。它只是调用咖啡实例中的getCost()方法。
  • 在我们的例子中,它是 simplecoffee ,费用为1.
  • 牛奶价格为0.5。

所以你们聚在一起1.5。

Greets Alan。

答案 3 :(得分:0)

  

任何人都可以解释Milk类和Simplecoffee类之间的链接以及在使用milk对象调用时如何执行方法getCost()。 getCost()方法如何返回1.5?

visualization of the Decorator calls in Head First Design Patterns做得更好。按照下面的绿色箭头。对Bundle extras = data.getExtras(); Bitmap imageBitmap = (Bitmap) extras.get("data"); mImageView.setImageBitmap(imageBitmap); 的调用是嵌套的,返回值也以绿色显示。该图片还显示了getCost() 如何包装 Milk类。

enter image description here