Mar 26th, 2023
The Decorator Pattern is a structural design pattern that allows us to add functionality to an object dynamically, without changing its interface. It is often used as an alternative to subclassing to extend the behavior of an object.
The Decorator Pattern consists of four main components: the Component
, ConcreteComponent
, Decorator
, and ConcreteDecorator
. The Component
is the abstract class that defines the interface for the objects we want to decorate. The ConcreteComponent
is the class that represents the basic object we want to decorate. The Decorator
is the abstract class that defines the interface for the decorators. The ConcreteDecorator
is the class that represents the actual decorator.
Let's take an example of a coffee shop. We have a Beverage
interface that defines the basic interface for all the beverages in the coffee shop. We have a Coffee
class that implements the Beverage
interface and represents a basic coffee. We want to add additional functionality to our coffee, such as adding milk or sugar, without changing the interface of the Coffee
class. We can use the Decorator Pattern to achieve this.
We can define our Component
as the Beverage
interface, which will have a getDescription()
and cost()
method. The ConcreteComponent
will be the Coffee
class, which implements the Beverage
interface and provides its own implementation of the getDescription()
and cost()
methods.
The Decorator
class will be the CondimentDecorator
abstract class, which will also implement the Beverage
interface. It will have a Beverage
instance variable to hold the object we want to decorate. It will also provide its own implementation of the getDescription()
and cost()
methods.
The ConcreteDecorator
classes will be the Milk
and Sugar
classes, which will represent the actual decorators. They will extend the CondimentDecorator
abstract class and provide their own implementation of the getDescription()
and cost()
methods.
The Client
class will create a Coffee
object and decorate it with Milk
and Sugar
decorators. It will then call the getDescription()
and cost()
methods on the decorated Coffee
object to get the description and cost of the coffee with milk and sugar.
By using the Decorator Pattern, we can add additional functionality to an object dynamically, without changing its interface. This makes it easier to extend the behavior of an object and also allows us to combine different behaviors together.
In conclusion, the Decorator Pattern is a powerful structural design pattern that allows us to add functionality to an object dynamically, without changing its interface. By using the Decorator Pattern, we can improve the flexibility and maintainability of our code.