开发者

Difference between the Composite Pattern and Decorator Pattern?

开发者 https://www.devze.com 2022-12-19 13:29 出处:网络
What is the difference between the Composite Pattern a开发者_运维技巧nd Decorator Pattern?They usually go hand in and hand. In that using the composite pattern often leads to also using the decorator

What is the difference between the Composite Pattern a开发者_运维技巧nd Decorator Pattern?


They usually go hand in and hand. In that using the composite pattern often leads to also using the decorator pattern.

The composite pattern allows you to build a hierarchical structure (such as a tree of elements) in a way that allows your external code to view the entire structure as a single entity. So the interface to a leaf entity is exactly the same as the entity for a compound entity. So the essence is that all elements in your composite structure have the same interface even though some are leaf nodes and others are entire structures. User interfaces often use this approach to allow easy composability.

http://en.wikipedia.org/wiki/Composite_pattern

The decorator pattern allows an entity to completely contain another entity so that using the decorator looks identical to the contained entity. This allows the decorator to modify the behaviour and/or content of whatever it is encapsulating without changing the outward appearance of the entity. For example, you might use a decorator to add logging output on the usage of the contained element without changing any behaviour of the contained element.

http://en.wikipedia.org/wiki/Decorator_pattern


The structure of composite pattern and decorator look the same but they have different intent.

Composite gives an unified interface to a leaf and composite.

Decorator decorator gives additional feature to leaf, while giving unified interface.


Examples

Composite pattern: classic windows folders and files. Windows folders are composites. files are leaves. A double click on either of them opens the file/folder - double click is unified interface.

Decorator pattern: Buffered io - java.io.FileWriter and java.io.BufferedWriter both extend java.io.Writer. java.io.BufferedWriter is composite and FileWriter is leaf. BufferedWriter adds additional responsibility (or feature) of buffering to FileWriter. write() method is unified interface, whereas buffering is additional feature.


A decorator can be viewed as a degenerate composite with only one component. However, a decorator adds additional responsibilities—it isn't intended for object aggregation.

This is what is said in "Design Patterns-Elements of Reusable Object Oriented Software" by the gang of four.


The difference is probably more one of purpose than implementation. In some instances the composite pattern is preferable to subclassing. For example, you can add the functionality that you want a class to have by adding instances of other classes to it and then exposing the functionality through a forwarding interface.

Decorators allow you to transparently add functionality, usually a single capability, to an class without clients of the instances of the class needing to know the that there's a decorator there - for example, a "login_required" decorator on a view in Django raises an exception if the user isn't logged in, but otherwise the view behaves as it would without the decorator.

In both cases you have one object embedded within another, but what you're trying to accomplish is arguably different.


Differences in structure

Here are the class diagrams from the GoF book, reproduced using PlantUML.

GoF Decorator class diagram

GoF Composite class diagram

Differences in intent

The intent of Decorator is to decorate a single component (the UML diagram really should show a multiplicity of one for the decorated component), whereas the intent of Composite is to group Components as a whole in the Composite (again, the UML should show a Composite containing one or more Components).

Decorator has a goal to add behavior (enhance behavior of the Operation() method) via the ConcreteDecorators, whereas Composite aims to collect Components.


The Decorator pattern can be used to extend (decorate) the functionality of a certain object statically, or in some cases at run-time, independently of other instances of the same class.

It's possible due to composition : Decorator contains Component and at the same time it implements Component interface.

The Composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies.

Implementing the composite pattern lets clients treat individual objects and compositions uniformly.

Even though the structure seems to be same, intent and use cases are different.

Use cases for Decorator pattern:

  1. Object responsibilities and behaviours should be dynamically added/removed
  2. Concrete implementations should be decoupled from responsibilities and behaviours
  3. subclassing is too costly to dynamically add/remove responsibilities

Key differences between these two patterns:

  1. Decorator is designed to let you add responsibilities to objects without subclassing. Composite's focus is not on embellishment but on representation
  2. Decorator adds/remove additional responsibilities - it isn't intended for object aggregation.

Useful posts in SE for better understanding :

Decorator Pattern for IO

When to Use the Decorator Pattern?


Composite:

  • Is a Tree Structure using recursion.
  • Leaf and Composite have same interface
  • Unity between objects

Decorator:

  • Is contain another entity.
  • Adding new functionality to a composite object without modifying it.
0

精彩评论

暂无评论...
验证码 换一张
取 消