One of the most important principles in software development is the open-closed design principle.

This design principle stresses that classes should be open for extension, but closed for modification.

The decorator design pattern embodies the open-closed design principle.

Person wrapping a gift

The decorator pattern does this dynamically at runtime, using composition.

This design pattern is known as a flexible alternative to using inheritance to extend behavior.

How Does the Decorator Design Pattern Work?

The decorator pattern structure

A key aspect of the decorator pattern is that all its classes are related, either directly or indirectly.

ConcreteComponent:these are the objects that you could decorate with different behaviors at runtime.

They inherit from the component interface and implement its abstract functions.

Decorator pattern pizza1

Decorator:this class is abstract and has the same supertype as the object it will decorate.

In the class diagram, youll see two relationships between the component and decorator classes.

The first relationship is one of inheritance; every decoratoris acomponent.

The decorator pattern pizza2

The second relationship is one of composition; each decoratorhas a(or wraps a) component.

ConcreteDecorator:these are the individual decorators that give a component a specific behavior.

You should note that each concrete decorator has an instance variable that holds a reference to a component.

This sample pizza app allows customers to order pizzas with multiple toppings.

The first class of the decorator pattern is the pizza interface:

The Pizza interface is the component class.

So, you could create one or more concrete classes from it.

The pizza company makes two main types of pizzas, based on their dough.

One key in of pizza has yeast dough:

The YeastCrustPizza is the first concreteJava classof the Pizza interface.

But its necessary to establish a relationship between the different decorators and the components that they will decorate.

The ToppingDecorator class represents the decorator class in this sample tool.

Now the pizza company can create many different toppings (or decorators), using the ToppingDecorator class.

Lets say a pizza can have three different types of toppings, namely cheese, pepperoni, and mushroom.

Thus, giving the pizza new behavior without altering the existing code (the yeast crust pizza).

The decorator pattern allows you to develop more secure code by not interfering with pre-existing secure code.

It instead extends existing code through composition.

Effectively preventing the introduction of new bugs or unintended side effects.

Due to composition a developer also has a lot of flexibility when using the decorator pattern.