装饰器模式与子类化
我可以通过添加子类来解决添加功能的问题那么为什么我应该使用装饰器模式装饰器模式的真正优势是什么?
I can solve the problem of adding functionality by adding sub classing then why should I use decorator pattern what's the real advantage of decorator pattern ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
GoF 设计模式一书指出了使用装饰器相对于子类化的两个主要优点:
从我的角度来看,仅防止子类爆炸就非常引人注目。
如果您有一个
TextWindow
,您想要使用子类独立且可选地向其中添加水平滚动、垂直滚动和边框,则必须为HorizontalScrollingTextWindow
定义子类,VerticalScrollingTextWindow
,HorizontalAndVerticalScrollingTextWindow
,BorderedTextWindow
,HorizontalScrollingBorderedTextWindow
,VerticalScrollingBorderedTextWindow
,HorizontalAndVerticaScrollingBorderedTextWindow
,如果您关心滚动和边框的顺序,还有更多。使用装饰器,您只需要定义两个滚动装饰器和一个边框装饰器。
The GoF Design Patterns book identifies two major advantages of using Decorators over subclassing:
From my point of view, preventing subclass explosion alone is quite compelling.
If you have a
TextWindow
to which you want to add horizontal scrolling, vertical scrolling, and borders all independently and optionally, using subclasses, you'd have to define subclasses forHorizontalScrollingTextWindow
,VerticalScrollingTextWindow
,HorizontalAndVerticalScrollingTextWindow
,BorderedTextWindow
,HorizontalScrollingBorderedTextWindow
,VerticalScrollingBorderedTextWindow
,HorizontalAndVerticaScrollingBorderedTextWindow
, and more if you care about the order of scrolling and bordering.With Decorators, you only need to define two scrolling decorators and one border decorator.
子类化可能会导致里氏替换原则出现问题。装饰器避免了这种情况。
装饰器的另一个优点是您正在写入(强制写入)接口。这使得测试变得更容易。确实,您的对象层次结构也可以写入接口,因此具有一些相同的优点,但是,我可以单独测试装饰器类的单个实现。我不能对子类做同样的事情,因为我总是将整个层次结构返回到基类。我无法单独测试新代码。
使用装饰器模式并遵循单一职责原则,我可以创建多个装饰器并按照我的意愿堆叠它们。我可以在运行时配置它。在继承中,我要么必须创建每个可能的分支(a->b->c,然后 a->c->b,从而复制代码并增加测试数量),或者创建 1 个层次结构,然后添加另一个层次结构需要时,但这会触发新的测试/发布周期。
这就是为什么您想要使用装饰器模式而不是子类化。
Subclassing can lead to issues with the Liskov substitution principle. The decorator avoids this.
Another advantage of the decorator is that you are writing (forced to write) to an interface. This makes things easier for testing. It is true that your object hierarchy can also be written to an interface and thus have some of the same advantages, however, I can test a single implementation of a decorator class in isolation. I cannot do the same with a subclass because I will always get the whole hierarchy back to the base class. I am unable to test the new code in isolation.
Using the decorator pattern and following the single responsibility principle, I can create several decorators and stack them anyway I wish. I can configure that at runtime. In inheritance I either have to create every possible branch (a->b->c then a->c->b, thus duplicating code and exploding the number of tests), or I create 1 hierarchy then add another when needed, but this triggers a new test/release cycle.
This is why you would want to use the decorator pattern instead of subclassing.
这是基于实际实现的差异。
装饰是子类化的另一种方法,用于扩展现有类的功能。这是我们应该使用子类或装饰器的一些场景。
1)子类主要用于扩展类似功能的情况
一组想要保留旧功能和新功能的类
在子类中
并且子类的所有实例共享相同的功能。如果我们
更改子类,然后它将反映所有实例
子班的数量。例如
层次关系,类似的类组。
父母->孩子->孙子。
Car->Maruti 800->Maruti 100(将具有 Maruti 800 和 New 的功能)
2) 装饰器模式用于装饰现有的类,而不改变旧的行为。例如类圆有简单的边框,但我们需要用红色边框装饰它,一段时间后,有些用户想要黄色边框,有些用户想要绿色边框的圆圈,有些用户想要红色和黄色边框的圆圈,有些用户想要红色和绿色边框的圆圈等,为此它是完美的模式,因为它将减少组合类的数量。下面是示例。
Icircle cir=new RedDecorator(new Circle()) 用红色装饰圆圈
Icircle cir=new YellowDecorator(new Circle()) 用黄色装饰圆圈
Icircle cir=new RedDecorator(new YellowDecorator(new Circle())) 装饰 红色和黄色的圆圈
,这里我们不需要创建RedAndYellow类装饰器。同样,我们可以用其他组合来装饰圆圈,而无需创建新的组合类集。
这样就减少了组合类的数量。
这是装饰器模式的有用链接
https://www.tutorialspoint。 com/design_pattern/decorator_pattern.htm
Here is the differences based on the real implementation.
Decoration is an alternative way of sub classing to extend the functionality of existing classes. Here is some scenario where we should use sub classing or decorator.
1) Sub classing mainly used in the case of extend the functionality of similar
group of classes which wants to retain the old functionality as well as new
in the sub classes
and all the instances of the sub classes share the same functionality. If we
make the changes of child classes and then it will reflect all the instaces
of child classes.Such as
a hierarchy relation ship, similar group of classes.
Parent->Child->GrandSon.
Car->Maruti 800->Maruti 100( will have the feature of Maruti 800 as well as New)
2) Decorator pattern is used to decorate the existing classes without changing the old behavior.Such as a class circle have plain border but we need to decorate it with red border,after some time some user wants circle with yellow color and some user wants circle with green border and some user wants red and yellow border circle and some user wants red and green border circle etc,for this it is the perfect pattern as it will reduces no of combination classes.Below is the example.
Icircle cir=new RedDecorator(new circle()) decorating the circle with red color
Icircle cir=new YellowDecorator(new circle()) decorating the circle with Yellow color
Icircle cir=new RedDecorator(new YellowDecorator(new circle())) decorating the
circle with red and Yellow, here we do not need to create RedAndYellow class decorator. same way we can decorate the circle with other set of combination without creating new set of combination classes.
In this way it reduces the no of combination classes.
Here is the useful link for decorator pattern
https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm
灵活性,这就是我认为的原因。
Flexibility, that's the reason IMO.
GoF 的一个例子:
基本上,通过使用装饰器模式,您可以在运行时向对象添加任意数量的附加责任,这是通过子类化无法实现的,而不会潜在地损坏代码结构或为子类添加许多重复的组合。
但有一件事,设计模式不是你必须使用的东西。
是否需要模式取决于您的特定问题、您是否想要长期维护代码、是否想要扩展以及诸如此类的许多其他因素。< br>
没有一种模式在所有情况下都有用。
适合一种情况的模式(装饰器或其他任何东西)对于另一种情况可能不是一个好的选择。
An example from GoF:
Basically, by using the decorator pattern you can add any number of additional responsibility to object at RUNTIME which you can not achieve by subclassing without potentially damaging your code structure or adding many duplicate combinations for subclasses.
But one thing, Design patterns are not something that you must use.
Whether a pattern is needed or not is dependent on your particular problem, you want to maintain the code for a long time or not, whether you want to extend or not and on many other factors like these.
And there is no pattern that is useful in all cases.
A pattern (decorator or anything else) suitable for a situation may not be a good choice for another situation.
来自 维基百科上的装饰器模式
装饰器模式的全部要点是动态添加额外的行为/功能,这在设计时当然是不可能的。
来自同一篇文章:
from Decorator pattern at wikipedia
The whole point of decorator pattern is to dynamically add additional behaviour/functionality, which is of course not possible at design time.
from the same article: