What Are Design Patterns?
- Defining Design Patterns
- The Learning Process
- Notes on Object-Oriented Approaches
- Python Design Patterns
Sitting at your desk in front of your workstation, you stare into space, trying to figure out how to write a new program feature. You know intuitively what must be done, what data and what objects come into play, but you have this underlying feeling that there is a more elegant and general way to write this program.
In fact, you probably don’t write any code until you can build a picture in your mind of what the code does and how the pieces of the code interact. The more you can picture this “organic whole,” the more likely you are to feel comfortable that you have developed the best solution to the problem. If you don’t grasp this whole right away, you might keep staring out the window for a time, even though the basic solution to the problem is quite obvious.
In one sense, you feel that the most elegant solution will be more reusable and more maintainable, but even if you are the sole likely programmer, you feel reassured when you have designed a solution that is relatively elegant and doesn’t expose too many internal inelegancies.
One of the main reasons computer science researchers began to recognize design patterns is to satisfy this need for elegant but simple reusable solutions. The term design patterns sounds a bit formal to the uninitiated and can be somewhat off-putting when you first encounter it. But, in fact, design patterns are just convenient ways of reusing object-oriented code between projects and programmers. The idea behind design patterns is simple: to write down and catalog common interactions between objects that programmers have frequently found useful.
One frequently cited pattern from early literature on programming frameworks is the Model-View-Controller framework for Smalltalk (Krasner and Pope, 1988), which divided the user interface problem into three parts. The parts were referred to as a data model, containing the computational parts of the program; the view, which presents the user interface; and the controller, which interacts between the user and the view (see Figure 4-1).
Figure 4-1 Model-View-Controller illustration
Each of these aspects of the problem is a separate object, and each has its own rules for managing its data. Communication among the user, the GUI, and the data should be carefully controlled, and this separation of functions accomplished that very nicely. Three objects talking to each other using this restrained set of connections is an example of a powerful design pattern.
In other words, design patterns describe how objects communicate without become entangled in each other’s data models and methods. Keeping this separation has always been an objective of good OO programming. If you have been trying to keep objects minding their own business, you are probably already using some of the common design patterns.
Design patterns started to be recognized more formally in the early 1990s by Erich Gamma,1 who described patterns incorporated in the GUI application framework ET++. The culmination of these discussions and a number of technical meetings was the book Design Patterns: Elements of Reusable Software, by Gamma, Helm, Johnson, and Vlissides.2 This best-selling book, commonly referred to as the Gang of Four, or “GoF” book, has had a powerful impact on programmers seeking to understand how to use design patterns. It describes 23 commonly occurring and generally useful patterns and comments on how and when you might apply them. Throughout the following chapters, we refer to this groundbreaking book as Design Patterns.
Since the publication of the original Design Patterns, many other useful books have been published. These include our popular Java Design Patterns: A Tutorial3 and an analogous book on C# design patterns.4 Rhodes5 maintains an interesting site describing how Python can make use of design patterns, as well.
Defining Design Patterns
We all talk about the way we do things in our everyday work, hobbies, and home life, and recognize repeating patterns all the time:
Sticky buns are like dinner rolls, but I add brown sugar and nut filling to them.
Her front garden is like mine, but in mine I use astilbe.
This end table is constructed like that one, but in this one, the doors replace drawers.
We see the same thing in programming, when we tell a colleague how we accomplished a tricky bit of programming so that they don’t have to re-create it from scratch. We simply recognize effective ways for objects to communicate while maintaining their own separate existences.
Design patterns are frequently used algorithms that describe convenient ways for classes to communicate.
It has become apparent that you don’t just write a design pattern off the top of your head. In fact, most such patterns are discovered rather than written. The process of looking for these patterns is called pattern mining and is worthy of a book of its own.
The 23 design patterns selected for inclusion in the original Design Patterns book were patterns that had several known applications and were on a middle level of generality, where they could easily cross application areas and encompass several objects.
The authors divided these patterns into three types: creational, structural, and behavioral.
Creational patterns create objects for you instead of having you instantiate objects directly. This gives your program more flexibility in deciding which objects need to be created for a given case.
Structural patterns help you compose groups of objects into larger structures, such as complex user interfaces or accounting data.
Behavioral patterns help you define the communication between objects in your system and control the flow in a complex program.