Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
149 views
Welcome To Ask or Share your Answers For Others

1 Answer

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...