Welcome!

ColdFusion Authors: Yakov Fain, Pat Romanski, Liz McMillan, Maureen O'Gara, Greg Ness

Related Topics: ColdFusion

ColdFusion: Article

Rethinking Decorators

An alternative to the Decorator pattern

In this article, writes Hal Helms, Ben Edwards (of Mach-II fame) and I rethink the Decorator design pattern.

Hal: So, did you see my CFDJ article on decorators?

Ben: Yeah. I saw it.

Hal: So, what did you think?

Ben: Let's just leave it at that: I saw it.

Ben and I were talking about my earlier CFDJ article on the Decorator design pattern [cfdj, vol. 6 issue 11]. In the article, I explained how the Decorator pattern could be used in situations in which there exists a base class with various options. In my article, I used the example of a base Coffee object with options such as ExpressoShot, WhippedCream, and FlavoredSyrup. The Decorator is useful in avoiding the sort of "class explosion" that would occur if we were forced to create separate classes reflecting all the possible permutations of base class with options: CoffeeWithExpressoShot, CoffeeWithWhippedCream, CoffeeWithExpressoShotAndWhippedCream, CoffeeWithExpressoShotAndWhippedCreamAndFlavoredSyrup, etc.

Ben: I'm not a big fan of Decorator as it's applied here.

Hal: What are your objections to it?

Ben: In order to have the Decorator work, as you explained in your article, you have to have all the options as subtypes of the base class.

Hal: Right. In the article example, FlavoredSyrup, WhippedCream, and ExpressoShot all extend the base Coffee class.

Ben: Making for an inheritance relationship.

Hal: Right.

Ben: And what's the test for creating inheritance relationships?

Hal: That the subclass "is-a" type of the base class.

Ben: And you consider WhippedCream to be a type of Coffee?

Hal: Well...no.

Ben: And, presumably, you'd need other options like ExtraHot, LowFoam, etc?

Hal: Right.

Ben: And those things aren't Coffee subtypes, are they?

Hal: No.

Ben: Well, that's my objection. It's not the best use of inheritance.

Hal: Yes, I see your point, but...

Ben: But what?

Hal: But it's such a danged useful pattern, I guess I'm willing to forgive a little impurity. It's a little like watching a movie. Typically, there's one presupposition that you have to accept - even one that may be a little far-fetched. You suspend disbelief just a little - and then you can accept the movie on its own terms. I guess I feel that way about the Decorator pattern.

Ben: The Decorator pattern was initially introduced by the "Gang of Four" in their book, Design Patterns. That was also the book that laid out the very useful, very good principle: "Prefer composition to inheritance." Composition exists when one class holds as an instance variable member(s) of another class. And that same good principle can be used to solve the problem of a base class with options. Using composition, we can keep separate the coffee from the extras you can add to it. I'd have the Coffee class composite its own options. See the way it's shown in Figure 1:

Ben: In this example the extras are added to the coffee rather than creating a wrapper around it. The coffee's description and price, for instance, are derived from the coffee itself and from the extras it has had added to it.

Hal: Yes, that would certainly work. What are the benefits of this approach over using the Decorator pattern?

Ben: Well, for one thing, the model conforms to the real world more closely than does the Decorator, where you end up with the bizarre situation where WhippedCream is a type of Coffee. As a matter of fact, the other day at the local Starboard coffee shop, I tried to order a cup of whipped cream. They wouldn't let me get whipped cream by itself; I could only get it in addition to a cup of coffee. They insisted that's why the coffees are separated on the menu from the "extras" - an "extra" is not a coffee. Separating the two better encapsulates the intent of each, providing more flexibility.

Hal: Agreed. Any other benefits?

Ben: You can tell the difference between the base coffee and the extras. With the Decorator pattern, the base class is subsumed by the Decorator class(es). I always know that I have a cup of Coffee - that has some extras added to it.

More Stories By Hal Helms

Hal Helms is a well-known speaker/writer/strategist on software development issues. He holds training sessions on Java, ColdFusion, and software development processes. He authors a popular monthly newsletter series. For more information, contact him at hal (at) halhelms.com or see his website, www.halhelms.com.

More Stories By Ben Edwards

Ben Edwards is a Sun Certified Java Programmer and holds a degree in
computer science from the Georgia Institute of Technology. He
currently trains developers on software engineering practices
focusing on Java, object-oriented programming, and software
architectures. Ben is also cofounder of the Mach-II project.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.