In the Head First Design
Patterns book, there is a chapter on Decorator pattern. The
coffee company currently has a Beverage abstract class which is extended by DarkRoast, Espresso, Decaf etc. Now they start selling condiments which spice up the coffee like whip, mocha etc. To accomodate, the first misguided attempt (that was a nice way to get us started), extends each of the subclasses above to factor in the whip, mocha etc. So we had a DarkRoastWhipMocha, a DarkRoastWhip, a DarkRoastWhipDoubleMocha etc. Then they suggested refactoring this with Decortator pattern. Whip, Mocha become Decorators that implement the same Beverage interface but can wrap concrete beverages like DarkRoast etc and then in the decorated cost() method, first invoke the wrapped (decorated) concrete class's cost() method and then add the cost of the condiment (decorator) before returning the cost.
My question is this... Is this really required? Condiments and coffee types are all products being sold at the outlet. So we just need to have different subtypes for each such condiment and/or product and each has its own cost() method returning its price from a product table for the model which is the unique key differentiating a mocha from a decaf from a whip. Then the Order object simply loops through all the order items which in this case are Beverages, calling each one's cost() method and calculating the sum() as the total of the order. This sounds simpler and cleaner to me. After all each condiment and coffee is a line item in a order slip. Why try to build one object that would try to represent a DarkRoastWhippedDoubleMocha by combining a Mocha decorator with a Whip decorator that wraps a DarkRoast beverage concrete object? Why use Decorator at all? May be iam not good in understanding things, but am i breaking rule here or am i just being stupid? If so how?
Thanks if you read this far... And lots of thanks in advance if you can clarify this to me :-)