The decorator pattern attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
![[Screenshot 2023-09-02 at 1.14.36 AM.png]]
![[Screenshot 2023-09-02 at 1.07.33 AM.png]]
![[Screenshot 2023-09-04 at 12.57.00 AM.png]]
### Key Points
* Decorators have the same supertype as the objects they decorate.
* You can use one or more decorators to wrap an object.
* Given that the decorator has the same supertype as the object it decorates, we can pass around a decorated object in place of the original (wrapped) object.
* The decorator adds its own behavior before and/or after delegating to the object it decorates to do the rest of the job.
* Objects can be decorated at any time, so we can decorate objects dynamically at runtime with as many decorators as we like.
### NOTE:
* One downside of the decorator pattern is that designs using this pattern result in a large number of small classes that can be overwhelming to a developer trying to use the Decorator-based API.
* Introducing decorators can increase the complexity of the code needed to instantiate the component. Once you've got decorators, you've got to not only instantiate the component, but also wrap it with who knows how many decorators.
* Decorators are usually created by using other patterns like Factory and Builder patterns.
* If you have code that relies on the concrete component's type, decorators will break that code. As long as you only write code against the abstract component type, the use of decorators will remain transparent to your code(they won't know they are working with a decorator). However, once you start writing code against concrete components, you'll want to rethink your application design and your use of decorators.