As we saw our previous designs using inheritance didn’t work out that well. In this article, decorator pattern is discussed for the design problem in previous set.
So what we do now is take a pizza and “decorate” it with toppings at runtime:
- Take a pizza object.
- “Decorate” it with a Capsicum object.
- “Decorate” it with a CheeseBurst object.
- Call getCost() and use delegation instead of inheritance to calculate the toppings cost.
What we get in the end is a pizza with cheeseburst and capsicum toppings. Visualize the “decorator” objects like wrappers. Here are some of the properties of decorators:
- Decorators have the same super type as the object they decorate.
- You can use multiple decorators to wrap an object.
- Since decorators have same type as object, we can pass around decorated object instead of original.
- We can decorate objects at runtime.
The decorator pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
Class Diagram:Image src: Wikipedia
- Each component can be used on its own or may be wrapped by a decorator.
- Each decorator has an instance variable that holds the reference to component it decorates(HAS-A relationship).
- The ConcreteComponent is the object we are going to dynamically decorate.
- The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime.
- The decorator pattern is an alternative to subclassing. Subclassing adds behavior at compile time, and the change affects all instances of the original class; decorating can provide new behavior at runtime for individual objects.
- Decorator offers a pay-as-you-go approach to adding responsibilities. Instead of trying to support all foreseeable features in a complex, customizable class, you can define a simple class and add functionality incrementally with Decorator objects.
- Decorators can complicate the process of instantiating the component because you not only have to instantiate the component, but wrap it in a number of decorators.
- It can be complicated to have decorators keep track of other decorators, because to look back into multiple layers of the decorator chain starts to push the decorator pattern beyond its true intent.
- Head First Design Patterns(Book)
In the next post, we will be discussing implementation of decorator pattern.
This article is contributed by Sulabh Kumar. If you like GeeksforGeeks and would like to contribute, you can also write an article and mail your article to firstname.lastname@example.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above