本书讲述了作者在学习设计模式过程中所积累的个人经验。书中包含很多实际的和可应用的实例,教你如何使用模式解决普通的编程问题,以及解释如何利用模式来进行先进的软件设计。本书清晰地演示了模式如何使整个开发过程变得更容易,还解释了面对对象设计的关键原则以及特定模式的概念和优势。通过直观的C++和Java实例,本书阐明了使用模式的原因以及如何使用模式,并解释了模式的实现。
Preface
From Object Orientation to Patterns
to True Object Orientation
From Artificial Intelligence to Patterns
to True Object Orientation
A Note About Conventions Used in This Book
Feedback
Acknowledgments
PART 1
An Introduction to Object-Oriented
Ware Development
Chaptor,
The Object-Oriented Paradigm
Overview
Before The Object-Oriented Paradigm:
Functional Decomposition
The Problem of Requirements
Dealing with Changes: Using Functional Decomposition
Dealing with Changing Requirements
The Object-Oriented Paradigm
Object-Oriented Programming in Action
Special Object Methods
Summary
Chapter 2
The UML-The Unfifed Modeling Language
Overview
What Is the UML?
Why Use the UML?
The Class Diagram
Interaction Diagrams
Summary
PART ll
The Limitations of Traditional
Object-Oriented Design
Chapter 3
A ProbIem That Cries Out for FIexible Code
Overview
Extracting Information from a CAD/CAM System
Understand the Vocabulary
Describe the Problem
The Essential Challenges and Approaches
Summary
Chapter 4
A Standard Object-Oriented SoIution
Overview
Solving with Special Cases
Summary
Supplement: C++ Code Examples
PART Ill
Design Patterns
Chapter 5
An lntroduction to Design Patterns
Overview
Design Patterns Arose from Architecture and Anthropology
Moving from Architectural to Software Design Patterns.
Why Study Design Patterns?
Other Advantages to Studying Design Patterns
Summary
Chapter 6
The Facade Pattern
Overview
Introducing the Facade Pattern
Learning the Facade Pattern
Field Notes: The Facade Pattern
Relating the Facade Pattern to the CAD/CAM Problem
Summary
Chapter 7
The Adapter Pattern
Overview
Introducing the Adapter Pattern
Learning the Adapter Pattern
Field Notes: The Adapter Pattern
Relating the Adapter Pattern to the CAD/CAM Problem
Summary
Supplement: C++ Code Example
Chapter 8
Expanding Our Horizons
Overview
Objects: the Traditional View and the New View
Encapsulation: the Traditional View and the New View
Find What Is Varying and Encapsulate It
Commonality/Variability and Abstract Classes
Summary
Chapter 9
The Brldge Pattern
Overview
Introducing the Bridge Pattern
Learning the Bridge Pattern: An Example
An Observation About Using Design Patterns
Learning the Bridge Pattern: Deriving It
The Bridge Pattern in Retrospect
Field Notes: Using the Bridge Pattern
Summary
Supplement: C++ Code Examples
Chaptor 1O
The Abstract Factory Pattern
Overview
Introducing the Abstract Factory Pattern
Learning the Abstract Factory Pattern: An Example
Learning the Abstract Factory Pattern: Implementing It
Field Notes: The Abstract Factory Pattern
Relating the Abstract Factory Pattern to
the CAD/CAM Problem
Summary
Supplement: C++ Code Examples
PART IV
Putting lt AIl Togrther: Thinking In Pattrrns
Chaptrr 11
How Do Expetrts Design?
Overview
Building by Adding Distinctions
Summary
Chaptrr 12
Solving the CAD/CAM Problem wlth Pattrrns_197
Overview
Review of the CAD/CAM Problem
Thinking in Patterns
Thinking in Patterns: Step 1
Thinking in Patterns: Step 2a
Thinking in Patterns: Step 2b
Thinking in Patterns: Step 2c
Thinking in Patterns: Step 2d (Facade)
Thinking in Patterns: Step 2d (Adapter)
Thinking in Patterns: Step 2d (Abstract Factory)
Thinking in Patterns: Step 3
Comparison with the Previous Solution
Summary
Chapter 13
The Principles and Strategies
of Design Patterns
Overview
The Open-Closed Principle
The Principle of Designing from Context
The Principle of Containing Variation
Summary
PART V
Handling Variations with Design Patterns
Chapter 14
The Strategy Pattern
Overview
An Approach to HandIing New Requirements
Initial Requirements of the Casc Study
Handling New Requirements,
The Strategy Pattern
Field Notes: Using the Strategy Pattern
Summary
Chapter 15
The Decorator Pattern
Overview
A Little More Detail
The Decorator Pattern
Applying the Decorator Pattern to the Case Study
Another Example: Input/Output
Field Notes: Using the Decorator Pattern
Summary
SuppIement: C++ Code Examples
Ohapter 16
The Singleton Pattern and the
Double-Checked Locking Pattern
Overview
Introducing the Singleton Pattern
Applying the Singleton Pattern to the Case Study
A Variant: The Double-Checked Locking Pattern
Field Notes: Using the Singleton and
Double-Checked Locking Patterns
Summary
Supplement: C++ Code Examples
Ohapter 17
The Observer Pattern
Overview
Categories of Patterns
More Requirements for the Case Study
The Observer Pattern
Applying the Observer to the Case Study
Field Notes: Using the Observer Pattern
Summary
Supplement: C++ Code Example
chapter 18
The TempIate Method Pattern
Overview
More Requirements for the Case Study.
The Template Method Pattern
Applying the Template Method to the Case Study
Field Notes: Using the Template Method Pattern
Summary
Chapter 19
The Factory Method Pattern
Overview
More Requirements for the Case Study
The Factory Method Pattern
Field Notes: Using the Factory Method Pattern
Summary
Chapter 2O
The Analysis Matrix
Overview
In the ReaI World: Variations
Case Study in Variation: An International E-Tail System
Field Notes
Summary
PART Vl
Endings and Beginnings
chapter 21
Oesign Patterns Reviewed
from the New Perspective of
Object-Orlented Design
Overview
A Summary of Object-Oriented Principles
How Design Patterns Encapsulate Implementations
Commonality/Variability Analysis and Design Patterns
Decomposing a Problem Domain into Responsibilities
Relationships Within a Pattern
Patterns and Contextual Design
Field Notes
Summary
Chapter 22
BibIiography
Design Patterns Explained: The Web Site Companion
Recommended Reading on Design Patterns
and Object orientation
Recommended Reading for Java Programmers
Recommended Reading for C++ Programmers
Recommended Reading for COBOL Programmers
Recommended Reading on eXtreme Programming
Recommended Reading on General Programming
Personal Favorites
INDEX
Design patterns and object-oriented programming. They hold such promise to make your life as a software designer and developer easier. Their terminology is bandied about every day in the technical and even the popular press. But it can be hard to learn them, to become proficient with them, to understand what is really going on.
Perhaps you have been using an object-oriented or object-based language for years. Have you learned that the true power of objects is not inheritance but is in "encapsulating behaviors"? Perhaps you are curious about design patterns and have found the literature a bit too esoteric and high-falutin. If so, this book is for you.
It is based on years of teaching this material to software developers, both experienced and new to object orientation. It is based upon the belietwand our experience-that once you understand the basic principles and motivations that underlie these concepts, Why they are doing what they do, your learning curve will be incredibly shorter. And in our discussion of design patterns, you will understand the true mindset of object orientation, which is a necessity before you can become profident.
As you read this book, you will gain a solid understanding of the ten most essential design patterns. YOu will learn that design patteins do not exist on their own, but are supposed to work in concert with other design patterns to help you create more robust applications. You will gain enough of a foundation that you will be able to read the design pattern literature, if you want to, and possibly discover patterns on your own.
Most importantly, you will be better equipped to create flexible and complete software that is easier to maintain.
From Object Orientotion to Patterns to True Object Orientation
In many ways, this book is a retelling of my personal experience learning design patterns. Prior to studying design patterns. I considered myself to be reasonably expert in object-oriented analysis and design. My track record had included several fairly impressive designs and implementations in many industries. I knew C++ and was beginning to learn Java. The objects in my code were wellformed and tightly encapsulated. I could design excellent data abstractions for inheritance hierarchies. I thought I knew object-orientation.
Now looking back, I see that I really did not understand the full capabilities of object-oriented design, even though I was doing things the way the experts advised. It wasn't until I began to learn design patterns that my object-oriented design abilities expanded and deepened. Knowing design patterns has made me a better designer, even when I don't use these patterns directIy.
I began studying design patterns in l996. I was a C++/object-oriented design mentor at a large aerospace company in the north-west. Several people asked me to lead a design pattern study group.
That's where I met my co-author, Jim Thott. In the study group, several interesting things happened. First, I grew fascinated with design patterns. I loved being able to compare my designs with the designs of others who had more experience than I had. I discovered that I was not taking full advantage of designing to interfaces and that I didn't always concern myself with seeing if I could have an object use another object without knowing the used object's type. I noticed that beginners to object-oriented design-those who would normally be deemed as learning design pattems too early-were benefiting as much from the study group as the experts were. The patterns presented examples of excellent object-oriented designs and illustrated basic object-oriented prinCiples, which helped to mature their designs more quickly By the end of the study sessions, I was convinced that design patterns were the greatest thing to happen to software design since the invention of objeet-oriented design. However, when I looked at my work at the time, I saw that I was not incorporating any design patterns into my code.
I just figured I didn't know enough design patterns yet and needed to learn more. At the time, I only knew about six of them. Then I had what could be called an epiphany I was working on a project as a mentor in object-oriented design and was asked to create a high-level design for the project. The leader of the project was extremely sharp, but was fairly new to object-oriented design.
The probIem itself wasn't that difficult, but it required a great deal of attention to make sure the code was going to be easy to rnaintain. Literally, after about two minutes of looking at the problem, I had developed a design based on my normal approach of data abstraction. Unfortunately, it was very clear this was not going to be a good design. Data abstraction alone had failed me. I had to find something better. two hours later, after appIying every design technique I knew, I was no better off. My design was essentially the same. What was most frustrating was that I knew there was a better design. I just couldn't see it. Ironically, I also knew of four design patterns that "lived" in my problem but I couldn't see how to use them. Here I was- supposed expert in object-oriented design-baffled by a simple problem!
Feeling very frustrated, I took a break and started walking down the hall to clear my head, telling myself I would not think of the problem for at least l0 minutes. Well, 30 seconds later, I was thinking about it again! But I had gotten an insight that changed my view of design patterns: rather than using patterns as individual items, I should use the design patterns together.
I had heard this before, but hadn't really understood it. Because patterns in software have been introduced as design patterns, I had always labored under the assumption that they had mostly to do with design. My thoughts were that in the design world, the patterns came as pretty much well-formed relationships between classes. Then, I read Christopher Alexander's amazing book, The Thaeless Way of BuiIding. I learned that patterns existed at all levels--analysis, design, and implementation. Alexander discusses using patterns to help in the understanding of the problem domain (even in describing it), not just using them to create the design after the problem domain is understood.
My mistake had been in trying to create the classes in my problem domain and then stitch them together to make a final system, a process which Alexander calls a particularly bad idea. I had never asked if I had the right classes because they just seemed so right, so obvious; they were the classes that immediately came to mind as I started my analysis, the "nouns" in the description of the system that we had been taught to look for. But I had struggled trying to
piece them together.
When I stepped back and used design patterns and Alexander's approach to guide me in the creation of my classes, a far superior solution unfolded in only a matter of minutes. It was a good design and we put it into production. I was excited-excited to have designed a good solution and excited about the power of design patterns. It was then that I started incorporating design patterns into my development work and my teaching.
I began to discover that programmers who were new to object-oriented design could learn design patterns, and in doing so, develop a basic set of object-oriented design skills. It was true for me and it was true for the students that I was teaching.
Imagine my surprise! The design pattern books I had been reading and the design pattern experts I had been talking to were saying that you really needed to have a good grounding in object-oriented design before embarking on a study of design patterns. Nevertheless, I saw with my own eyes, that students who learned object-oriented design concurrently with design patterns learned object-oriented design faster than those just studying object-oriented design. They even seemed to learn design patterns at almost the same rate as experienced object-oriented practitioners.
I began to use design patterns as a basis for my teaching. I began to call my classes Pattern Oriented Design: Design Patterns from Analysis to Implementation.
I wanted my students to understand these patterns and began to discover that using an exploratory approach was the best way to foster this understanding. For instance, I found that it was better to present the Bridge pattern by presenting a problem and then have my students try to design a solution to the problem using a few guiding principles and strategies that I had found were present in most of the patterns. In their exploration, the students discovered the solution--called the Bridge pattern--and remembered it.
In any event, I found that these guiding principles and strategies could be used to "derive" several of the design patterns. By "derive a design pattern," I mean that if I looked at a problem that I knew could be solved by a design pattern, I could use the guiding principles and strategies to come up with the solution that is expressed in the pattern. I made it clear to my students that we weren't really coming up with design patterns this way. Instead, I was just illustrating one possible thought process that the people who came up with the original solutions, those that were eventually classified as design patterns, might have used.
My abilities to explain these few but powerful, principles and strategies improved. As they did, I found that it became more useful to explain an increasing number of the Gang of Four patterns. In fact, I use these principles and strategies to explain 12 of the l4 patternms I discuss in my design patterns course.
I found that I was using these principles in my own designs both with and without patterns. This didn't surprise me. If using these strategies resuIted in a design equivalent to a design pattern when I knew the pattern was present, that meant they were giving me a way to derive excellent designs (since patterns are excellent designs by definition). Why would I get any poorer designs from these techniques just because I didn't know the name of the pattern that might or might not be present anyway? These insights helped hone my training process (and now my writing process). I had already been teaching my courses on several levels. I was teaching the fundamentals of object-oriented analysis and design. I did that by teaching design patterns and using them to illustrate good examples of object-oriented analysis and design. In addition, by using the patterns to teach the concepts of object orientation, my students were also better able to understand the principles of object orientation. And by teaching the guiding principles
and strategies, my students were abIe to create designs of comparable quality to the patterns themselves.
I relate this story because this book follows much the same pattern as my course (pun intended). In fact, from Chapter 3 on, this book is very much the first day of my two-day course: Pattern Oriented Desiyn: Desiyn Patternsfrom Analysis to Implementation.
As you read this book, you will learn the pattems. But even more importantly, you will Iearn why they work and how they can work together, and the principles and strategies upon which they rely It wiIl be useful to draw on your own experiences. When I present a problem in the text, it is helpfuI if you imagine a similar problem that you have come across. This book isn't about new bits of information or new patterns to apply, but rather a new way of looking at
object-oriented software development. I hope that your own experiences, connected with the principles of design patterns, will prove to be a powerful ally in your learning.
Alan Shalloway
December 2000