aspose file tools*
The moose likes OO, Patterns, UML and Refactoring and the fly likes Question about HF Design Patterns book Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "Question about HF Design Patterns book" Watch "Question about HF Design Patterns book" New topic
Author

Question about HF Design Patterns book

aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182
Hi,
I have a question about an example given in the book named above.
In chapter 3: Decorator Pattern, a problem is given about a StarBuzz coffee application.We have an existing code that caters to around 4 basic beverages and now we want to apply different condiments (Milk,Mocha,Whip etc..) to it.
Question: Instead of Decorator pattern, can't we make a Condiments interface seperately and have all Mocha, Milk,Whip etc. condiments implement it and then define their own cost() methods?
Next, we keep a List of all these condiments in the Beverage class (Aggregation) and to calculate the total cost, do something like the following pseudocode:


If anybody who has read this book and understood can spare some time, I shall be greatful.
aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182
Second call for help, please!
May be the authors can spare some time?
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17259
    
    6

Yes that is a possibility. As long as that interface is already being used for Condiments. However, is whip a condiment. To me it sounds like an action.

And also note that the example in the book is to show Decorator, so they are only going to show Decorator, it never means that there aren't other possible solutions, just that this is an example that demonstrates Decorator, no matter how contrived something could be.

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182
Thanks Mark.
Actually, I was taking a view that the examples given in the book are such that the pattern being explained is supposed to be the best fit for a given problem. Specially because in the book other approaches are considered and rejected for their demerits.
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

The solution that you have provided will mandate that the beverage classes need to change. isnt?
That is one of the things, according to the problem statement, the implementor does not want to do.

Conceptually, a simple coffee does not need to know what add ons it is being served with. It will be the responsibility of someone who is making the coffee to add on the condiments(or to "decorate" the coffee with the condiments).


apigee, a better way to API!
aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182

The solution that you have provided will mandate that the beverage classes need to change. isnt?


Ok, I "misspoke" about the List of condiments being maintained by the Beverage class.Its election season in the US you see, so I should be pardoned :-)

Let me propose a solution slightly different from the one earlier.
Say we have a third class called Drink.
Drink will have a Beverage and a list of Condiments.
The pseudocode is the same except that it now resides in the Drink class.
So, now, we have not changed the Beverage class and we have a list of Condiments as well. Beat that.
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

aditee:
Say we have a third class called Drink.
Drink will have a Beverage and a list of Condiments.


Is Drink an interface or an implementation?
If it is an implementation, what interface does it implement?

If it is an interface, then as a coffee maker I have to know 2 interfaces, one for Plain Beverages and other for Drink.

If the interface of Drink is the same as beverage, then probably without knowing you are using the decorator pattern
aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182

Is Drink an interface or an implementation?


At the risk of sounding stupid, let me say : Neither.
Its just a calling class. So, if a customer orders a beverage (Drink is the client class), we create a new instance of that beverage and get its cost.
Next we maintain a List<Condiments> and keep adding to this list all the condiments that the customer orders.
Next, iterate through this list and keep adding the costs to the beverage cost, and you get the total.

Well, may be I've been thinking too much and said something stupid, having totally lost my way...But I need to get this concept home once and for all.Kindly bear with me.
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

I would not comment on the name of the classes(Drink in particular).

I assume in the following statement:
Next we maintain a List and keep adding to this list all the condiments that the customer orders.

"We" is the StarBuzz coffee application?

If yes, then now the coffee application has the logic of calculating the price. In the initial design, the disposed entity(beverage) has the logic of calculating its own price.
The condiments know that they have to add their price to the one obtained from super() and the basic beverages know their own prices.

Additionally, the design must also depend on what comes out of the coffee application.
If the whole intention is to calculate the price then probably you can use your design. But the intention is to dispense the beverage.
In your design, the client will get a beverage and has to call some other method to get the cost. (correct me if i am wrong)
In the initial design, the only object that one knows is the beverage. It may be used to calculate cost or to drink!

Having, said the above, there is no such thing as a perfect design. Different people think of things in different ways. Design patterns are present because they identify "most common solutions to common problems".
Your solution may not be the "most common" but it still is a solution
aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182

"We" is the StarBuzz coffee application?

Yes, or the Drink class that I named.Lets call it StarBuzz from now onwards.


If yes, then now the coffee application has the logic of calculating the price. In the initial design, the disposed entity(beverage) has the logic of calculating its own price.

If by "own" price, you mean just the beverage price(i.e without condiments), then the logic still resides inside the Beverage class, StarBuzz is just calling it to calculate the total cost.


In the original design, the condiments know that they have to add their price to the one obtained from super() and the basic beverages know their own prices.

That means strong coupling between condiments and Beverage.It may be desirable business-wise, but may be not from a coding point of view.


In your design, the client will get a beverage and has to call some other method to get the cost.

Well, the client will get the cost from the beverage only, and to calculate the total cost, it will iterate over the list of condiments and add them to the beverage-only cost.


In the initial design, the only object that one knows is the beverage.

Yeah, we create only Berverage reference though we are assigning Condiment Objects to it many times. Is that a requirement to know of only one Class Reference ?
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

aditee:
If by "own" price, you mean just the beverage price(i.e without condiments)

No, "own" price means price of anything disposed by the coffee application. Beverage or Beverage + condiments, whatever.

aditee:
That means strong coupling between condiments and Beverage.

I beg to differ. Strong coupling will be if i keep condiments inside the beverage. This means beverage will always know the condiments.
If i decorate beverage with condiments then beverage does not know condiments and condiments only knows that it is supposed to be always served with "something". I would not like to call it strong coupling because that is the nature of condiments. They are never served alone but always as an add-on.

aditee:
Yeah, we create only Berverage reference though we are assigning Condiment Objects to it many times.

Now, you are confusing me.

You said:

Let me propose a solution slightly different from the one earlier.
Say we have a third class called Drink.
Drink will have a Beverage and a list of Condiments.

I thought you are saying that the starbuzz coffee application creates one more object that is a composition of beverage and a list of condiments.

aditee:
Is that a requirement to know of only one Class Reference ?


Ok i change my initial statement a little. What i meant was:

the only *interface* that one knows is the beverage.

Now instead of the pseudo code can you put in the real code and let us discuss from there.
aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182
Okay, here you go:
Nitesh Kant
Bartender

Joined: Feb 25, 2007
Posts: 1638

In your implementation you have changed the Beverage class to contain the condiments.
This is something that does not seem correct. Beverages in my opinion should not know condiments.

Now, if you make one more class, which is a composite of condiments and beverage(this is what i thought you were saying) then it will have one method cost().
Now, is there a difference between the contract(interface) of the new composite class and the old beverage class?
I think no, because they just have one method cost()
If there is no difference why do you want to define a new interface?

If it is the same interface then you are using the decorator pattern.
aditee sharma
Ranch Hand

Joined: Jul 22, 2008
Posts: 182
ok, perfect.
Thanks for your time.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Question about HF Design Patterns book