Decorator Design Pattern
Start course
3h 59m

In this course, we will learn the concepts of microservice and spring framework with a focus on design patterns.

Learning Objectives

  • Learn about various design patterns

Intended Audience

  • Beginner Java developers
  • Java developers interested in learning how to Build and Deploy RESTful Web Services
  • Java Developers who want to develop web applications using the Spring framework
  • Java Developers who want to develop web applications with microservices
  • Java Developers who wish to develop Spring Boot Microservices with Spring Cloud


  • Basic Java knowledge

Hello, dear friends. In this video, we will examine the Decorator Design Pattern. So, let's begin. In software engineering, a decorator design pattern is used to add additional features or behaviors to a particular instance of a class while not modifying the other instances of the same class. Decorators provide a flexible alternative to subclassing for extending functionality. This pattern is very important to understand because once you know the techniques of decorating, you'll be able to give your or someone else's objects new responsibilities without making any code changes to the underlying classes. This pattern is also very useful and frequently asked about in Java interviews when discussing design patterns.

In other words, the decorator pattern uses composition instead of inheritance to extend the functionality of an object at runtime. Suppose we want to implement different kinds of cars. We can create an interface "Car" to define the assemble method and then we can have a basic car.

Furthermore, we can extend it to sports car and luxury car. So, let's look at the UML schema of the decorator pattern. The ConcreteComponent class is the one for which we'll like to add additional behaviors at runtime. The ConcreteDecorator is the decorator class, which holds the logic to decorate a given component. The AbstractDecorator class aggregates any other type of component, which allows us to stack components, one on top of the other. Also, both the ConcreteComponent and Decorator classes implement a common interface as Component. So, let's look at the advantages and disadvantages. First, let's start with the advantages. Decorator provides greater flexibility than static inheritance and it avoids the need to place feature-laden classes higher up the hierarchy.

Decorators simplifies coding by allowing you to develop a series of functionality targeted classes instead of coding all of the behavior into the object. Also, the decorator enhances the extensibility of the object because changes are made by coding new classes. But, there are also some disadvantages of decorator pattern, such as: 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. So, when should we use this pattern in our projects? When you want to add responsibility to objects transparently and dynamically without affecting other objects. Or in cases where you want to add responsibility to the objects that you may want to change in the future, the use of the decorator design pattern will be beneficial for the project.

I know that listening theoretically is not enough to fully understand the decorator pattern, so let's see in code with an example. Create a project and name it Decorator pattern. So, we previously spoke about a car, so let's use a car object in our example. First, we need a Car interface. Add a method as assemble. This interface is our component interface. Let's define component implementation. Add a new car and name it BasicCar, implements Car. Let's override the method. Now, we need decorator. CarDecorator implements Car. First, we will add Car as protected. Decorator class implements the component's interface and it has, it has a relationship with the component interface. The component variable should be accessible to the child decorator classes. So, we will make this variable protected. Define constructor, override method. Now, we have to add car types as decorator creators; sports cars.

Define constructor and override method. Now, the other creator. Okay, done. Now, we have finished structure, let's use. First, create a SportsCar, call assemble method. Now, create a LuxuryCar, call assemble method. Done. Okay, let's run the application and see the results. Awesome. See, you can see both the sports car and the luxury car, and that means our application has executed flawlessly. And I believe that concludes our discussion of decorator. In the following video, we will look at the flyweight pattern. So, I'll see you there.


About the Author
Learning Paths

OAK Academy is made up of tech experts who have been in the sector for years and years and are deeply rooted in the tech world. They specialize in critical areas like cybersecurity, coding, IT, game development, app monetization, and mobile development.