An overview
This fortunate coincidence got me immediately involved with patterns as well. In fact, thanks to Steven, I started using patterns in my daily development shortly after making my first steps in Visual FoxPro, long before Visual FoxPro 3.0 was actually released.
Before I started working on this chapter, I sat down to think about what I was going to write. All of a sudden, patterns came to mind a remote topic I hadn't dealt with in a long time. Fortunately, this feeling didn't last long because I realized that the only reason patterns seemed remote was the fact that I hadn't written an article or given a talk on the subject in quite a while. However, I still use patterns on a daily basis. Now that I think of it, just a couple of hours ago I implemented a perfect "strategy" pattern in combination with a "bridge" pattern. But these things now come so naturally that I don't even realize I'm using them.
You might not be familiar with the two pattern names I mentioned above, but once you read this chapter, things should be a lot clearer. In fact, if you were familiar with those particular patterns, you would have a pretty good idea of what I did.
In this chapter, I'll introduce the basic ideas behind object-oriented design patterns. I'll also give you a couple of actual pattern examples, such as the two I mentioned above. Note that this chapter is not meant to replace a pattern catalog; it only gives some quick examples in a less detailed fashion. Pattern catalogs are usually quite a bit bigger than the one you are holding. They introduce a huge number of patterns in a language-independent fashion. Every pattern is explored in a great level of detail, typically including case studies of known uses, diagrams, code samples and other useful information.
Erich Gamma's book (Design Patterns, Elements of Reusable Object-Oriented Software, ISBN 0-201-63361-2, Gamma, Helm, Johnson, Vlissides) is the classical example of a patterns catalog. Every serious object-oriented developer should have a copy of this book on his desk. When I worked with Steven Black, he always bought a copy of this book for every programmer on the team. I picked up the same habit and continue to do the same. It has always worked out well, improving overall product quality and cutting a good chunk of time off our meetings.
While Erich Gamma's book was one of the first to pick up the topic of patterns, there are now an incredible number of books that have the word "pattern" in their titles. Some of them are good, but a lot of them seem to be looking for the "quick buck." Check out my Web page (www.eps-software.com) for an up-to-date list of recommended reading.
What exactly is an "object-oriented design pattern"?
A pattern is an abstract solution to a standard problem "class." When creating object-oriented applications, you'll notice that many problems seem to occur on a regular basis. In fact, this isn't a characteristic of object-oriented development. One issue that comes up in almost every application is the requirement of writing data to files. The solution is simple. You open a file, write the data and close the file. This three-step process is a perfect example of a design pattern. It isn't object-oriented, nor is it very sophisticated, but it's a real pattern nevertheless.
If you've used FoxPro 2.x, you might have used another pattern: the Foundation Read. This pattern solved the problem of applications shutting down automatically after startup. I could continue to list examples of patterns you might have used, but I think you get the idea. Patterns are everywhere!
Object-oriented design patterns are specific to object-oriented development. Due to the widely accepted ideas of reuse, encapsulation and polymorphism, patterns make more sense in the object-oriented world than anywhere else. Instead of reusing code, we are simply reusing design that is known to work. This has obvious advantages. We don't have to come up with new solutions all the time. We also don't have to think of all possible complications because somebody else has already taken care of that.
Our first pattern
A simple object-oriented design pattern is the "strategy" pattern. This pattern describes how one object uses various strategy objects to achieve a task. For instance, an invoicing module could use a number of tax-calculation objects to calculate taxes depending on the location of the customer. We could create all the required logic in one object that knows about all kinds of taxes that apply in the area of the customer. However, this would be inflexible, hard to maintain and hard to extend if new taxes had to be added, new areas included, or if the laws changed. For this reason, we could create a number of different tax-calculation objects. Depending on the area the customer lives in, a different object could be invoked.
Note that I haven't yet talked about the actual implementation of this pattern. That's fine. In fact, patterns aren't concerned at all with implementation because they're language independent. Later in this chapter I'll give you some implementation examples, which should be considered only as additional information.
One common terminology
Patterns not only give us guidance, but they also provide a terminology that allows us to "talk objects" more efficiently. How important is it to use this terminology? Does it make things harder than necessary? To answer these questions I'd like to give you an example of pattern terminology. As mentioned above, patterns can be found in object-oriented design as well as in other areas of development and even outside the programming world. In fact, we use pattern terminology in our daily lives.
If I tell you "I have an elevator in my office," this statement is quite clear. By using the word "elevator," I'm able to give you an accurate description of a piece of equipment that I use all the time. If I couldn't use the term "elevator," I'd have a hard time giving you a good description. I would say something like, "My office has a metal box that runs up and down on a cable and it can transport people from one floor to the other." However, this still wouldn't be as accurate as the earlier statement. In fact, it might not even be true. After all, I'm not quite sure whether that elevator runs on a cable or on a rail. Also, the way you would imagine this "metal box" might be quite different from what it really is. I could describe its appearance in more detail, but then I'd be giving you a specific description of my elevator and you might wrongly assume that all elevators look like mine.
In the end, I would have delivered a complicated description, possibly giving you some wrong impressions, and I only wanted to tell you that I'm too lazy to take the stairs so I had an elevator installed.
How much easier was it to use the pattern term "elevator" rather than the description? I'd say quite a bit. Did it make the language unnatural and unnecessarily complex? I don't think so. In my opinion, the opposite is true, but it required you to know the meaning of the word "elevator." The same is true in the field of object-oriented design.
By the way: Did you notice that the statement "I have an elevator in my office" didn't tell you any details about my specific elevator, yet it was sufficient and more effective than the exact description? That's a very important observation. When talking about patterns, you're not concerned with implementation details. There is no need to tell you that my elevator has a total capacity of eight people, it has a wooden interior with mirrors, and nice elevator music plays at all times. Equally, I wouldn't care how you implemented the strategy pattern in your application. You could create visual classes or plain source code. You could use a case statement to decide what object to use, or you could use precompiler statements. I couldn't care less, but the use of the strategy pattern is an important design milestone I care very much about.
The detailed information might be useful, but it would detract from my initial statement and therefore make it less clear, a consequence that might be fine when making small talk, but fatal when doing object-oriented design.