We are constantly facing new design problems. We always solve the problems, but sometimes we find that we have backed ourselves into a corner. Sometimes we find that the solution has serious drawbacks, and sometimes we create bad solutions. By reusing good, well-proven, and flexible solutions we minimize these risks and we reach the desired result faster. A tool to use for this is patterns. Thanks to the higher abstraction level that comes from patterns, we can also start and succeed with even larger design problems. Pattern awareness also leads to better understanding between developers—system development is very much about communication.
I’ve heard it many times. Patterns are academic nonsense, useless and elitist. If this is also how you feel, my aim in this chapter is to show you the opposite, because nothing could be more wrong. Patterns can be very pragmatic, highly useful in day-to-day work, and extremely interesting to all (or at least most) developers. Maybe you haven’t noticed, but I have already discussed several patterns. One example is the Domain Model pattern [Fowler PoEAA] that I brought up in Chapter 1, "Values to Value." In this chapter, we will discuss three different categories of patterns: namely Design Patterns (generic and -application-type specific), Architectural Patterns, and Domain Patterns.
Even if you are already pattern-conscious, I think you’ll find this chapter interesting. I won’t reuse old explanations, but will provide my own view of the patterns. For example, the discussion I’m going to use will be very Domain Model-focused, which is not typically the case when it comes to Design Patterns, for example. If nothing else, I hope you’ll find the reflections here and there of interest.
Before getting started, though, I’d like to take you through a generic discussion of the concept of patterns and why you should learn about them.
A Little Bit About Patterns
Patterns provide simple, elegant solutions to recurring design problems. The key advantages patterns provide are flexibility, modularity, and creating understandable and clear design. Note that I skipped reusability, although it’s a bit unfair. Patterns take away focus from code reuse and move the focus to knowledge reuse instead. So patterns are very much about reusability, too, but just not in the way we usually think about reuse.
When you study patterns, you might think "OK, isn’t that how we always do it?" An important point about patterns is that they aren’t invented, but rather harvested or distilled. It’s about proven solutions. But the solution part isn’t the only piece of a pattern. They are described in three pieces: the context, the problem, and the solution.
Learning from your mistakes is very powerful, but from time to time it’s nice to take a shortcut by studying other people’s amassed knowledge, which is a good reason for learning patterns. Let’s see if we can find other reasons.
Why Learn About Patterns?
The most obvious reason is probably that patterns are good abstractions that provide building blocks for system design.
If a development team is patterns-conscious, patterns become a very important part of the language. Instead of having to describe each and every design idea in minute detail, it’s often enough to say a pattern name and everybody in the team can evaluate whether or not it’s a good idea for that particular problem. Adding patterns to the team’s language might be the single most important reason for embracing patterns because the common understanding, richness, and expressiveness of the language increase. Again, development is very much about communication.
Another reason I like patterns is that being able to utilize patterns is a long-lasting skill. As a comparison, I learned SQL in around 1988, and I can still make a good living from just working with that. The products and platforms I work with have changed several times, though the underlying concepts are the same. Patterns are similar. The Design Patterns book [GoF Design Patterns] came out in 1995, and it’s still extremely relevant today. Also worth pointing out is that patterns are language-/product-/platform-agnostic. (Different platforms might have specific support for certain implementation variations, and it’s also the case that the [GoF Design Patterns] have been written with object orientation as an assumption.)
If you study Design Patterns [GoF Design Patterns], you will find that the patterns there are very much in line with the principles of good object-oriented design. What is good object-oriented design, you might ask? Robert C. Martin discusses some such principles in Agile Software Development: Principles, Patterns, and Practices [Martin PPP]. Examples include the Single Responsibility Principle (SRP), the Open-Closed Principle (OCP) and the Liskov Substitution Principle (LSP).
Patterns are not only great with up-front design, they are very usable (perhaps even more) during refactoring..."My code is just becoming messier and messier. Ah, I need to use that pattern!" It’s like the chicken or the egg problem, but I decided to start with patterns in this book and discuss refactoring after that (in the next chapter).
Is There Something to Look Out for Regarding Patterns?
Honestly, I see little reason for not learning about patterns, but there is at least one very common negative effect to look out for. What I’m thinking about is that for developers who have just learned about patterns, it’s very common that they feel compelled to squeeze in 17 patterns in each and every solution. Most often that effect won’t stay around for very long.
What might stay around for a little longer is the risk of over-design. If not 17 patterns, there might at least be a lot of thought about how a problem should be solved. The initial solution doesn’t feel right because it doesn’t use a certain pattern.
You might get the feeling that the patterns concept is the silver bullet. It’s not—of course not—it’s just another tool for the toolbox.
Patterns are often perceived individually as being pretty "simple," but they get very complex in context and combination with other patterns. I don’t remember how many times I’ve heard people on the newsgroups say something like "I understand pattern X, but when I try to use it in my application together with pattern Y and pattern Z, it’s extremely complex. Please help!" That isn’t really a reason not to learn about patterns. This book will address that to some degree, but not here and now; first we will discuss some patterns in isolation.
I believe Joshua Kerievsky’s Refactoring to Patterns [Kerievsky R2P] sets this straight by pointing out again and again that the way to most often use patterns isn’t to use them in up-front design, but to refactor toward or to patterns.
OK, time to move over to the first pattern category. Let’s see if we can create an "Aha!" and not just a "Huh?" for those of you who are pattern newcomers.