Sunday, May 6, 2012

Design Patterns: Understand Your Tools

This past week, I had an email discussion with a colleague regarding a particular design pattern.  He came across a recommendation to use the Strategy pattern in a particular situation, and he didn't see the benefit of the recommendation (framed in his many years of experience).  It was clear from the sample code that he sent me that he understood the solution to the pattern, but he needed some help with some other areas.

Understand the Benefits of the Pattern
Design patterns describe a problem in our environment and the core of a solution to that problem (paraphrasing Christopher Alexander -- see Learn the Lingo: Design Patterns for the actual quote).  It is important that we understand the problem that the pattern is trying to solve.  Many times, patterns help us with the S.O.L.I.D. principles.  These principles from Robert C. Martin (a.k.a. Uncle Bob) are guidelines to help us create well-designed objects and are considered to be high on the list of best practices.  I'd recommend any developer working in an OO language to take some time to study these principles.

When we took a closer look at the Strategy pattern (or more specifically, the sample implementation), we found that by using the pattern, we would be following the Single Responsibility Principle, the Open-Closed Principle, and the Dependency Inversion Principle (the "S", "O", and "D" of the S.O.L.I.D. principles).

But this does not determine whether we should be using the pattern.

Understand the Costs of the Pattern
Everything has trade-offs; design patterns are no different.  The problem is that when we're looking for solutions (whether on-line, through colleagues, or in training) the costs of patterns are often not discussed.  This is generally where we need to start digging a little deeper.

When talking about costs, sometimes it is simply added complexity to our system.  Sometimes, there is a side effect that we need to write some additional code to mitigate.  The costs are not always "show stoppers".  In fact, they generally are not.  What's important is to determine whether we are willing to undertake those costs in order to get the benefits.

In the case of the Strategy pattern, two of the costs that affected our situation were that (1) Clients must be aware of the different Strategies and (2) Increased number of objects.

Here's the Problem
Often, we'll come across recommendations like "This is a great place to use a Factory Method" or "Inversion of Control would be good here".  These recommendations often include the benefits that we would get from the pattern in a particular situation.  What is generally lacking, though, is any discussion about the costs of the pattern.  This is where we need to do a bit of research on our own.

There are tons of good resources for design patterns that do go through the benefits and costs.  One good book is Agile Principles, Patterns, and Practices in C# by Robert C. Martin and Micah Martin.  Martin and Martin take a look at a set of design patterns in the context of actual application scenarios.  And sometimes the recommendation is that a particular pattern may not be appropriate.  Here's a quote from a section that looks at the Template Method pattern:
"Design patterns are wonderful things.  They can help you with many design problems.  But the fact that they exist does not mean that they should always be used.  In this case, Template Method was applicable to the problem, but its use was not advisable.  The cost of the pattern was higher than the benefits it yielded."

Understand Your Tools
Ultimately, Design Patterns are tools for our toolbox.  We don't need to use a particular tool for every job.  We won't use all of the tools for a particular job.  The key is that we understand our tools: what they are good for and what we need to be careful of.

If we do not understand the benefits of a design pattern, then we may end up applying that pattern in a situation where we do not get the benefits.  In that situation, we only get the costs with no benefit -- a very bad design decision.

Conversely, if we do not understand the costs of a design pattern, then we may end up applying that pattern in situations where it is not warranted.  We end up getting the costs whether we know about them or not, and we may find that we've backed ourselves into a corner and have to deal with side effects that we were not expecting.

One more thing to consider if you are working in a team environment: If you determine that the use of a particular pattern is appropriate in your project, make sure that all of the team members understand the pattern.  If they do not understand the pattern, then you have 2 choices: (1) don't use the pattern, or (2) teach the pattern to the other developers.  My preference is always to improve the knowledge of other developers.  That way, you can grow as a team, and you won't have to make the same decision on the next project.

Ultimately, in my discussion with my colleague, we both left with a better understanding of the Strategy pattern.  And even though we may not use it in our next projects, we know where it is in the toolbox.

To wrap things up, I'll point to a blog post from Rocky Lhotka: On the Use and Misuse of Design Patterns.  Rocky's post has enough important points that I go back and re-read it periodically; you should, too.

Happy Coding!

No comments:

Post a Comment