Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Lists Instead of Decorator Pattern?

Tags:

A Decorator Pattern use case from "Head First: Design Patterns" book made me have this question. I'll try to write it down:

It's a coffee shop system with some coffees and a lot of condiments you can put in them (for an extra cost), you need to be able to order and charge for a coffee with any condiments the costumer desires, and to avoid having total mayhem (e.g. booleans to keep track of the condiments) Decorator Pattern is used. We have an abstract Beverage class, each type of coffee as concrete components and each condiment as concrete decorators wrapping up a Beverage, like this:

Beverage Class Diagram

And so we have the following process returning a coffee cost:

Coffee Cost Delegation

My question is: Why not implement this with Lists instead of the Decorator? We could have a list of Condiment in each Beverage and calculate the cost by iterating through the List. To order a coffee we would just have to instantiate it once and add the desired condiments, avoiding declarations like:

// Using second image example Beverage beverage = new DarkRoast(beverage); beverage = new Mocha(beverage); beverage = new Whip(beverage); 

In addition to that we would have more flexibility for operations like giving discount for a coffee not including it's condiments, once we won't have decorators wrapping up the coffee. This is a matter that have been long studied, I know I'm missing something or maybe I got something wrong, so if you have any thoughts on this I would love to know and discuss it further.

like image 859
Perestroika Avatar asked Apr 22 '17 22:04

Perestroika


People also ask

When should we use the decorator pattern?

The Decorator pattern is best when the decorators modify the behavior of the methods in the interface. A decorator can add methods, but added methods don't carry through when you wrap in another decorator.

What are the reasons for using the decorator design pattern?

Decorator design pattern allows us to dynamically add functionality and behavior to an object without affecting the behavior of other existing objects within the same class. We use inheritance to extend the behavior of the class.

What is the advantage of decorator pattern?

Advantage of Decorator PatternIt enhances the extensibility of the object, because changes are made by coding new classes. It simplifies the coding by allowing you to develop a series of functionality from targeted classes instead of coding all of the behavior into the object.


2 Answers

Decorator pattern is about decorating ( enhancing ) an object with additional features at runtime.

Suppose you already have a class, lets call it class A which implements an interface IA. Now if there is a requirement of adding an additional feature for which we want it to have a method ,someAlignFeatureToA() which was not there in A. Now you have an option of extending the class A. Another approach is Composition which should be favoured over Inheritance. You can wrap the object of class A in another class B implwmenting the same Interface as of A i.e. IA. This way for the client code it would be easy to accept the object of class B as it has the same interface as of A. (Assumption is the code is well written which depends on the Abstractions (interface IA) and not on concrete classes like class A).

This way the inheritance chain is not too long and you can add additional features at runtime easily.

Now coming to your question : Yes in the example you took in your question, a List fits better, but I feel its the intention of the author to explain usuage of Decorator pattern with an easy example. Suppose Coffee is made up of milk, coffee mix and sugar. Coffee mix is further made up of smaller components . Here the solution emerges similar to Composite pattern.

Decorator pattern is design pattern based on Enhancement of Behavior. Java IO streams uses this where behavior (method implementation) is enhanced by the decorating class (one stream is wrapped with another to enhance the previous one)

like image 69
nits.kk Avatar answered Oct 25 '22 12:10

nits.kk


What you are telling is a way to calculate the total cost of the beverage. In more general terms you are proposing an alternative way to merge & execute the main behavior of each of the derived objects supposed by the Decorator Pattern, by adding up them into a list. And it is not quite an OO approach too.

But the original intent of Decorator Pattern goes to a much wider perspective other than that. It is Adding extended functionalities to an object dynamically. Which means I have some object O1 & I want it to convert it into another object O2 with extended functionality & yet to be those 2 are interchangeable.

So it is about how we can manage the Object Evolution against the Object Lifecycle. Hope you got the idea. :))

like image 23
Supun Wijerathne Avatar answered Oct 25 '22 12:10

Supun Wijerathne