当前位置: 首页 > 面试题库 >

为什么在装饰器设计模式中需要装饰器?

刘运浩
2023-03-14
问题内容

假设我有一个名为的类A,并且我想使用装饰器设计模式。如果我错了,请纠正我,但是要使其正常工作,我们需要创建一个装饰器类,例如ADecorator,该类将保留对A实例的引用,所有其他装饰器将对其进行扩展以添加功能。

我不明白为什么我们必须创建装饰器类而不是使用A实例?


问题答案:

装饰器模式用于动态地(即在运行时)向对象添加功能。通常,在编写类时,对象将具有固定的功能。但是重要的一点是,对象的功能以对对象的客户端透明的方式扩展,因为它实现的接口与原始对象将责任委托给装饰对象的接口相同。

装饰器模式适用于对象可能具有许多可选功能的场景。如果没有装饰器模式,则必须为每个对象选项配置创建一个不同的类。一个非常有用的示例来自O’Reilly 的
Head First Design Patterns 一书。它使用听起来像StarBucks的咖啡店示例

因此,您可以使用成本等基本咖啡。

public double cost(){
     return 3.45;
}

然后,客户可以添加成本为0.35的奶油,因此您现在可以使用成本方法创建CoffeeCream类:

public double cost(){
    return 3.80;
}

然后,客户可能想要价格为0.5的摩卡咖啡,而他们可能想要含奶油的摩卡咖啡或不含奶油的摩卡咖啡。因此,您将创建类CoffeeMochaCream和CoffeeMocha。然后,客户需要双层奶油,因此您要创建一个类CoffeeCreamCream…等。最终得到的是类爆炸。请原谅这个可怜的例子。有点晚了,我知道这很简单,但确实表达了这一点。

相反,您可以使用抽象的cost方法创建Item抽象类:

public abstract class Item{
    public abstract double cost();
}

您可以创建扩展Item的具体Coffee类:

public class Coffee extends Item{
    public double cost(){
       return 3.45;
    }
}

然后,您创建一个CoffeeDecorator,以扩展相同的接口并包含一个Item。

public abstract class CoffeeDecorator extends Item{
     private Item item;
     ...
}

然后,您可以为每个选项创建具体的装饰器:

public class Mocha extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.5;
   }

}

请注意,装饰器如何不在乎它只是包装为Item的那种对象?它使用item对象的cost()并简单地添加其自己的成本。

public class Cream extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.35;
   }

}

现在可以使用以下几类进行大量配置:例如

 Item drink = new Cream(new Mocha(new Coffee))); //Mocha with cream

要么

 Item drink = new Cream(new Mocha(new Cream(new Coffee))));//Mocha with double cream

等等。



 类似资料:
  • 问题内容: 基本上,我想知道为什么必须创建一个抽象装饰器类来实现(或扩展)某些接口(或抽象类)。为什么所有新的“装饰类”都不能简单地实现(或扩展)基本抽象对象本身(而不是扩展抽象装饰器类)? 为了更具体一点,我将使用设计模式书中涉及咖啡饮料的示例: 有一个称为的抽象组件类 简单的饮料类型,例如简单扩展 为了装饰饮料,创建了一个抽象类,该类扩展并具有 假设我们要添加“牛奶”调味品,将创建一个扩展 我

  • 装饰(Decorator) Intent 为对象动态添加功能。 Class Diagram 装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能。装饰者的方法有一部分是

  • 当我回顾了“decorator”设计模式的大量示例时,我刚刚想到了一些示例,这些示例主要是关于更改总是返回字符串的方法,或者像cost()这样聚合数字的方法。 这真的是装饰器设计模式的唯一用法吗? 我只知道它用于Java IO API。 但我想有其他的东西,打印一个文本。一些真实的东西。我找了那么多,却找不到合适的样品。

  • 主要内容:介绍,实现,Shape.java,Rectangle.java,Circle.java,ShapeDecorator.java,RedShapeDecorator.java,DecoratorPatternDemo.java装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。 我

  • 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。 我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。 介绍 意图:动态地给一个对象添加

  • 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。 这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。 我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。 介绍 意图:动态地给一个对象添加