Design Patterns and Practice
As part of a larger program of career development and training, Lou and I have been moderating weekly discussions of the Gang of Four design patterns. Each week, two engineers are each assigned a pattern to learn and to present. The presentations include UML diagrams, discussion of functionality as well as where the patterns are used in the Atalasoft code base as well as if and where they appear in the real world.
I was reading this criticism of the use of design patterns and to a certain degree, I concur. Let me explain why. Knowing design patterns is absolutely useful. When I learned them, there weren’t names for the patterns. I discovered them either second hand by reading other people’s code and pragmatically by using what I thought was best at the time for the problem at hand. If you do this enough, the patterns become part of you.
I think that on the front end of learning patterns, it is entirely easy to fall into the trap of “when all you have is a hammer, everything starts to look like a nail.” The first thing you think of is the pattern. I claim that if you think of the pattern at all, you’re probably not thinking about the problem enough. The application of patterns should not consume thought. Instead, it should be as natural as breathing.
The use of patterns is like the use of literary device. There are (probably) an infinite number of ways in which the same general thought can be expressed, but I doubt you will find a single quality writer who started off a chapter thinking, “I’m introducing a character here so it’s best to paint a picture of the character. That calls for simile. Yeah, simile will do it. I think I’ll also use some ironic juxtaposition.” This type of writing feels forced. I’ve read code where the application of design patterns also felt forced. Remember when you first learned about for-loops? I’m betting your use of loops was forced in the same way. Same thing.
For our upcoming 8.0 release, I did a major refactoring of image memory allocation. I sat down with Jacob so that he could do a tech presentation about it*. While going through the code, I pointed out patterns we covered. This particular stretch of code included factory, singleton, template method, memento and (the possibility for) chain of responsibility. And I will say quite honestly that I didn’t think about any of those when I architected this and subsequently wrote the code. My main thrust was that the memory for images should be able to come from anywhere. The memory should be able to move when it is not in use. There should be little or no impact on our typical customers. Impact on advanced customers should feel logical. The mechanism should interoperate with unmanaged code equally as well as will managed code. It should fit naturally into my future plans for memory allocation specifically and dotImage in general. I hit all of those things, and most of my time was spent thinking about impact, testing, and how to fail fast and fail hard when something was out of kilter. I believe this is where my concentration should be, not on patterns.
It sounds oddly Zen: to best use patterns, you should not think about patterns.
*You may be wondering way Jacob, an engineer on Vizit is doing a presentation on dotImage low-level image memory. There are several reasons:
- I could do this in my sleep – that means that I don’t need the practice. I’m passing that opportunity on.
- By requiring someone else to do the presentation, I’m ensuring that at least one other person will know this code and the reasons why it is the way it is. You rarely learn something more effectively than having to explain it to someone else.
- I will find out how well I did by seeing how the information comes back in another route (like playing telephone).