What Is the Decorator Design Pattern?
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.
With the decorator design pattern, you can easily extend a class by giving it new behavior without altering its existing code. 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?
Though the decorator pattern is an alternative toclass inheritance, it does incorporate some aspects of inheritance in its design. A key aspect of the decorator pattern is that all its classes are related, either directly or indirectly.
A typical decorator design pattern has the following structure:

From the class diagram above you can see that the decorator pattern has four major classes.
Component:this is an abstract class (or interface), which serves as the supertype for the decorator pattern.

ConcreteComponent:these are the objects that you can decorate with different behaviors at runtime. They inherit from the component interface and implement its abstract functions.
Decorator:this class is abstract and has the same supertype as the object it will decorate. In the class diagram, you’ll see two relationships between the component and decorator classes. The first relationship is one of inheritance; every decoratoris acomponent. 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.
Implementing the Decorator Design Pattern in Java
A sample pizza ordering application can adequately demonstrate how to use the decorator pattern to develop applications. This sample pizza application 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’re able to create one or more concrete classes from it. The pizza company makes two main types of pizzas, based on their dough. One type of pizza has yeast dough:

The YeastCrustPizza is the first concreteJava classof the Pizza interface. The other type of pizza available is flatbread:
The FlatbreadCrustPizza class is the second concrete component and, like the YeastCrustPizza class, it implements all the abstract functions of the Pizza interface.
The Decorators
The decorator class is always abstract, so you can’t create a new instance directly from it. But it’s 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 application. Now the pizza company can create many different toppings (or decorators), using the ToppingDecorator class. Let’s say a pizza can have three different types of toppings, namely cheese, pepperoni, and mushroom.
Cheese Topping
Pepperoni Topping
Mushroom Topping
Now you have a simple application implemented using the decorator design pattern. If a customer were to order a yeast crust pizza with cheese and pepperoni, the test code for that scenario will look as follows:
Running this code will produce the following output in the console:
As you can see, the output states the type of pizza along with its total cost. The pizza started as a yeast crust pizza for $18.00, but with the decorator pattern, the application was able to add new features and their appropriate cost to the pizza. Thus, giving the pizza new behavior without altering the existing code (the yeast crust pizza).
With the decorator pattern, it’s possible to also apply the same behavior to an object as many times as you wish. If a customer orders a pizza with everything on it, and some extra cheese, you can update the main class with the following code to reflect this:
The updated application will produce the following output in the console:
The Advantages of Using the Decorator Design Pattern
The two major advantages of using the decorator design pattern are security and flexibility. 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. You can implement a new decorator at any time to add new behavior, without altering existing code and disrupting the application.
The singleton pattern has some solid use cases, so make sure you know how to use it.
Your iPhone forgets what you copy, but this shortcut makes it remember everything.
Your phone is a better editor than you give it credit for.
So much time invested, and for what?
If an AI can roast you, it can also prep you for emergencies.
Windows is great, but adding this makes it unstoppable.