In this interview, Erich Gamma, co-author of the landmark book, Design Patterns, talks with
Bill Venners about how design patterns are problem solution pairs, how design patterns help you
understand intent and tradeoffs, and how to become a better designer through practice.

Erich Gamma lept onto the software world stage in 1995 as co-author of the best-selling book
Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley, 1995) [1].
This landmark work, often referred to as the Gang of Four (GoF) book, cataloged 23 specific
solutions to common design problems. In 1998, he teamed up with Kent Beck to produce JUnit [2],
the de facto unit testing tool in the Java community. Gamma currently is an IBM Distinguished
Engineer at IBM's Object Technology International (OTI) lab in Zurich, Switzerland.
He provides leadership in the Eclipse community, and is responsible
for the Java development effort for the Eclipse platform [3].

On October 27, 2004, Bill Venners met with Erich Gamma at the OOPSLA
conference in Vancouver, Canada.
In this interview, which will be published in multiple installments
in Leading-Edge Java on Artima Developer,
Gamma gives insights into software design.

In Part I: How to Use Design Patterns,
Gamma describes gives his opinion on the appropriate
ways to think about and use design patterns, and describes the difference between
patterns libraries, such as GoF, and an Alexandrian pattern language.

In this third installment, Gamma discusses
how design patterns are problem solution pairs, how design patterns help you
understand intent and tradeoffs, and how to become a better designer through practice.

Design patterns are problem solution pairs

Bill Venners: My first real insight into object-oriented programming came from
reading Scott Meyers' Effective C++. In that book he has a guideline that
says, "Make sure public inheritance models 'is-a.'" That guideline helped me truly
understand inheritance for the first time. However, a later Effective C++
guideline says, "Model 'has-a' or 'is-implemented-in-terms-of' through composition." That
guideline didn't help me as much to figure out what to do with composition.

In the GoF book, however, I found several more concrete prescriptions for using
composition. GoF talks about using composition to model relationships like "adapts-a,"
"proxies-a," and "decorates-a." If you just look at the UML diagrams in GoF, a lot of
them look similar. Most of them use composition with interface inheritance. Where the
patterns differ is in the problem you are trying to solve with those composition and
inheritance relationships. Even though the class diagram might look similar, the design
intent is different. What is the role of intent in design patterns?

Erich Gamma: A pattern is always a problem-solution pair that can be applied in
a particular context. Although the solutions might look similar in different patterns, the
problems they are solving are different. In fact from ten thousand meters most patterns
solve a problem by adding a level of indirection. What is interesting is how this
indirection comes about and in particular why it needs to happen. Therefore if you just
look at the solution to the problem, it isn't that enlightening and everything starts to look
the same. When we wrote design patterns we often had this feeling—they all
started to look like the Strategy pattern.

Initially we described only solutions. We had an initial catalogue of about 20 pages.
Experienced developers had no problem understanding what we were up to and they
rewarded us with comments like, "Yes, I've done that." However, we noticed that the rest
had a hard time to get it at all. We showed different flavors of indirection. We showed a
delegation. But basically we had a solution looking for a problem. Alexander's [4]
view on patterns combined with the feedback from early readers helped us to not only
focus on the solution but also on the problem part. A pattern has a problem and a
solution, and you need to see both. For example, strategy and state have the same
solution: you delegate to a separate object, and use a class hierarchy of objects
conforming to an interface to vary behavior. But the problem is different. Strategy is
about plugging in an algorithm, and state is about changing behavior when a class's state
changes, as in a state machine.

Understanding intent and tradeoffs

Bill Venners: In the GoF book, you say, "Knowing the design patterns in this
book makes it easier to understand existing systems." How?

Erich Gamma: You can explain an existing system with patterns way more
compactly than without. Patterns help you compress a dialogue about design. A good
example is what Kent Beck and I did in the last section of our Eclipse book [5]. We
described some of the Eclipse designs with patterns. It was really amazing how compact
you can get. You can say, "that's a composite." You don't have to say much more about it.
People know what it is.

What's interesting is that we did this pattern analysis on an earlier version of Eclipse, and
the analysis is still correct for the latest version. So while the screenshots are out of the
date the patterns we identified are still up to date.

Once you understand that the system is using a certain set of patterns, and you know that
those patterns have certain limitations and liabilities, you're in a better position to
understand the intent of the developer that came up with the solution. The pattern tells
you about the intent but also about the tradeoffs. Once you know the limitation of a
design, you're in a better position to be a good citizen of say a reusable design like a
framework. One of the worst things that can happen is that you start to fighting against a
design, because you didn't really understand what it was, not honoring its intent and you
start sounding a little like Frank Sinatra "I'll do it my way".

Bill Venners: You just said that patterns tell us about tradeoffs. What do you
mean by that?

Erich Gamma: Design is always about tradeoffs. There are alternatives and each
alternative has different consequences. When I design, I always make decisions. And
each decision has advantages and disadvantages. That was also an important lesson we
had learned when we wrote Design Patterns. Initially we were so excited
about the patterns; we only saw the positive effects. It took some time until readers
pointed out that this isn't realistic. So we made another pass, and also discussed the
liabilities. At this point we also learned that identifying a pattern is much simpler than
actually writing it. So here is an example: you have just added the Strategy pattern, and
you have more flexibility. But the tradeoff is that you now have more objects and an
additional level of indirection. Right? Everything has a price in engineering. That's what I
mean by tradeoff. One of the key values of a pattern is that it captures these tradeoffs so
that you don't have to do the analysis again. When you're walking along in a design flow,
a pattern can act as a signpost. If you go this way, then you know that this is the tradeoff.
I think this is highly valuable.