To understand decorator pattern let us consider a scenario inspired from the book “Head First Design Pattern”. Suppose we are building an application for a pizza store and we need to model their pizza classes. Assume they offer four types of pizzas namely Peppy Paneer, Farmhouse, Margherita and Chicken Fiesta. Initially we just use inheritance and abstract out the common functionality in a Pizza class.
Each pizza has different cost. We have overridden the getCost() in the subclasses to find the appropriate cost. Now suppose a new requirement, in addition to a pizza, customer can also ask for several toppings such as Fresh Tomato, Paneer, Jalapeno, Capsicum, Barbeque, etc. Let us think about for sometime that how do we accommodate changes in the above classes so that customer can choose pizza with toppings and we get the total cost of pizza and toppings the customer chooses. Let us look at various options. Option 1 Create a new subclass for every topping with a pizza. The class diagram would look like:
This looks very complex. There are way too many classes and is a maintenance nightmare. Also if we want to add a new topping or pizza we have to add so many classes. This is obviously very bad design.
Option 2: Let’s add instance variables to pizza base class to represent whether or not each pizza has a topping. The class diagram would look like:
The getCost() of superclass calculates the costs for all the toppings while the one in the subclass adds the cost of that specific pizza.
// Sample getCost() in super class public int getCost() { int totalToppingsCost = 0; if (hasJalapeno() ) totalToppingsCost += jalapenoCost; if (hasCapsicum() ) totalToppingsCost += capsicumCost; // similarly for other toppings return totalToppingsCost; }
// Sample getCost() in subclass public int getCost() { // 100 for Margherita and super.getCost() // for toppings. return super.getCost() + 100; }
This design looks good at first but lets take a look at the problems associated with it.
Price changes in toppings will lead to alteration in the existing code.
New toppings will force us to add new methods and alter getCost() method in superclass.
For some pizzas, some toppings may not be appropriate yet the subclass inherits them.
What if customer wants double capsicum or double cheeseburst?
In short our design violates one of the most popular design principle – The Open-Closed Principle which states that classes should be open for extension and closed for modification. In the next set, we will be introducing Decorator Pattern and apply it to above problem.
References: Head First Design Patterns( Book).
Feeling lost in the vast world of System Design? It's time for a transformation! Enroll in our
Mastering System Design From Low-Level to High-Level Solutions - Live Course and embark on an exhilarating journey to efficiently master system design concepts and techniques.
What We Offer:
Comprehensive Course Coverage
Expert Guidance for Efficient Learning
Hands-on Experience with Real-world System Design Project
Proven Track Record with 100,000+ Successful Enthusiasts
Commit to GfG's Three-90 Challenge! Purchase a course, complete 90% in 90 days, and save 90% cost click here to explore.
Last Updated :
31 Oct, 2023
Like Article
Save Article
Share your thoughts in the comments
Add Your Comment
Please Login to comment...