Eag*_*arn 5 c# java design-patterns
我很难理解Erich Gamma's书中Design Patterns关于Decorator模式的以下实现建议.
省略抽象的Decorator类当您只需要添加一个职责时,无需定义抽象的Decorator类.
我不明白为什么需要抽象的Decorator类呢?为什么不能所有装饰器只是直接实现/继承IComponent/Component?
装饰器为其他一些类添加了一些功能.他将旧功能的所有消息转发到装饰类.新功能由装饰器本身处理.如果要添加的功能不止一种,那么将旧功能转发到装饰类的代码放在多个类中.这就是使用抽象装饰器的原因.
在上面的示例中,我们希望使用功能A oder功能B从IComponent层次结构中解除某些类."someFunctionality()"的转发代码将在两个类中.所以我们提取一个抽象装饰器类(避免重复).派生装饰器中唯一的代码现在是要添加的功能,再加上调用超类的方法.这很重要,因为如果转发的逻辑发生变化,则必须仅更改超类方法.您可以使用功能A或B修饰FirstDerived和SecondDerived.
如果要使用不超过一个功能来装饰现有类,则不必提取"someFunctionality"的转发,因为只有一个装饰器放置此转发代码.
Gamma的实现提示是省略抽象装饰器类,其唯一目的是转发ClassHierarchy的功能,以便在具体装饰器中只有添加其新功能的重要代码.
我建议你在没有抽象装饰的情况下开始.但是,如果添加第二个装饰器,则必须删除重复的代码,从而在重构期间提取抽象类.
我根本看不到为什么需要抽象Decorator类?为什么所有装饰器都不能简单地直接实现/继承IComponent / Component?
The purpose of the abstract class in the Decorator pattern is to eliminate code duplication. The crux of the Decorator pattern is to allow you to wrap an existing Component with new responsibilities. This wrapping is done by creating a new class that IS-A component and HAS-A component :
public class Decorator implements Component {
private Component component;
public Decorator(Component component) { this.component = component; }
}
Run Code Online (Sandbox Code Playgroud)
Imagine that you introduce two more decorators. You would now have to implement similar code in both your new decorators. The abstract decorator can help you solve exactly this problem. By moving the above code to an abstract class, all your concrete decorators can inherit from it and avoid the need to re-implement the decorator skeleton manually.
I understand that the Decorator in the above example doesn't do much; however, imagine a situation where you want to disallow further decoration based on some condition. For example, don't allow any more toppings on a Pizza if the cost will exceed 15$. The abstract decorator can take care of this by calling the getCost function on the component in the constructor. This will result in a call to all the getCost function of all the decorators and give you a final cost. If getCost()>15, the application can inform the user that the cost cannot exceed 15$. Such code reuse is the real motivation behind the abstract decorator class.