I was very sorry when I found out that your intentions were good and not what I supposed they were. — Sitting Bull after the Battle of Little Big Horn
Easing into a Selection
We have a bumper crop of peaches this year, and I’ve been peeling, slicing and freezing peaches for the last couple of weeks. It reminded me that Part III of Choosing a PHP Design Pattern is due. This is the third and last installment in the series. You might want to take a look at Part I and/or Part II of this series before or after looking at this post.
Wouldn’t it be nice if you could type in the name of your intended project and up pops the best possible design pattern for that project? Even if you hold your breath until you turn blue, that’s not going to happen. However, such a project (a DP Picker) is a worthy one. You can begin to narrow down your choices by asking whether your project is one that belongs in the Creational, Structural or Behavioral categories. If you’re lucky, you’ll end up with the Creational category and only have five patterns from which to choose. (Since the Singleton is one of that group, you really only have to choose from four.) The following is a summary of each category. (The major sections of Learning PHP Design Patterns begin with a brief overview of each category. See pages 77, 121 and 167.)
- Choose Creational When…You want to abstract the instantiation process and separate the use of the object from its creation.
- Choose Structural When…You want to create larger structures from classes and objects.
- Choose Behavioral When…You must focus of the communication between objects and the interaction between those objects.
Suppose I want to make an app that spends a lot of time loading and unloading different types of data and/or objects—which is something I often do. I’d probably want to choose a Creational pattern because I’m instantiating and removing lots of objects. Never mind which one; that’ll come later, but I’ve certainly narrowed my choices. On the other hand, if my main focus is going to be a game program, I’m going to need a good deal of inter-object communication and interaction and so I’m going to be looking at the Behavioral patterns. That will leave me with about half of the 24 patterns, but it’s a start.
Attention to Intention
The 24 different patterns have 24 different intentions (The Adapter pattern is counted twice since it has both Class and Object versions). The Gang of Four advise us to study the intention of each pattern to help make a decision about which one to use. Rather than listing them here, you can use the table developed in an earlier post, Design Pattern Variation and Intents Table, where you can also download the code for the table. Click the Play button to see the table:
So what is an intention? Let’s take a look at the Proxy intention to get an idea:
Proxy Intention: Provide a surrogate or placeholder for another object to control access to it.
That kind of intention is pretty easy to envision. A login is one example where the user is logging into the Proxy and not the Real object. This was shown in Chapter 11 of Learning PHP Design Patterns and in a post on the Proxy pattern on this blog. (Click below to continue.)
Other intentions can be a bit more esoteric. However, after working with design patterns for a long time now, I found it more difficult to find an intention that wasn’t pretty clear as far as I was concerned. So, give yourself some time, and what may appear a bit vague becomes clearer. For example, consider the Builder’s intention,
When I first read that, it didn’t make a lot of sense, but after creating a Builder example, it made a good deal of sense. About the only thing that would enter a decision about using the Builder is whether it is the most appropriate or would the Abstract Factory do a better job. Instead of having 24 choices, I now have two decisions. By comparing the two design patterns and looking at the details of my projected application, I can make a better decision. By eliminating design patterns with intentions that don’t meet a project need, I can reduce my choices. The general categories of Creational, Structural and Behavioral are the starting points, and just by selecting one category, you’ve eliminated half of the catalog. Likewise, the more experience you develop by working with design patterns the process becomes faster and easier. Even better, at some point you can recognize projects where you can re-use software from another project using a design pattern.
Builder Intention: Separate the construction of a complex object from its representation so that the same construction process can create different representations.
Encapsulate What Varies
For the longest time, I relied on the principle of encapsulating what varies as the guiding principle in making decisions as you can see from previous posts. You can see all of the variations in the Design Pattern Variation and Intents Table. (Click Play button above and look at the “What can vary?” column.)
Choosing a design pattern on the basis of what varies is the opposite of avoiding what causes redesign. You want to consider what you want to be able to vary without causing redesign. In creating a game using the State pattern, I wanted to incrementally add new functionality to the player. Beginning with Rock, Paper, Scissors, I was able to further add Lizard and Spock, and I didn’t need to redesign it. I just added the new states and incorporated them in existing states. You don’t always know what changes you may want to make (or have to make) but consider the possibilities. Then use the Design Pattern Variation and Intents Table to see which pattern to use (You can just call it the Magic Table):
So how do you use the Magic Table to make decisions about which design pattern to use? Actually, as I learned after using it for a long time, you use it in conjunction with the other elements helpful in choosing a design pattern. If you have a clear idea of what varies (or what you want to vary) then it’s easy. Just match the variation with the design pattern. However, rarely is it that easy. Usually, I find myself starting with the general groupings in the three main categories and shaking the bag of variation and poking and pulling. While that may sound more random than it really is, there’s still no silver bullet. (You simply get several pewter bullets.)
After three posts on how to choose a design pattern, I still come back to “shaking the bag.” It’s a matter of taking all of the parts and giving it a shake to see what comes together. Some things come together quickly, while others are more resistant to fitting in. However, all of the elements in these three posts make up the kinds of strategies that aid in choosing a design pattern that best meets the requirements of your project. Having all of these tools—or elements—will not make the chore of selecting a design pattern easy. As you know, nothing about design patterns is easy until you start reusing them—the payoff. The task, though, of selecting a design pattern is made less difficult by considering the suggested steps covered in these posts.
Choosing a PHP Design Pattern: Part III —Intentions & Encapsulating Variation by William Sanders, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.