What Are Software Design Patterns Hiding From You?
We can all get overwhelmed at times by jargon terms like MVC (Model View Controller), Abstract Factory, and GOF (Gang of Four) patterns. Let me admit something: for a long time I was comfortable with only one pattern, Singleton. I completely understood Singleton and used it in many software projects. As a result, I know all the tradeoffs that Singleton offers.
If you’re familiar with Singleton, you may laugh because it’s such an easy pattern to apply. It was the only pattern I knew, and I used it everywhere. Unfortunately, in some situations Singleton is inappropriate, so I ended up misapplying it. The problem was that I did not fully understand the software design patterns. If I had understood how to use a pattern, I would not have misused or overused Singleton.
Eventually, I met an experienced web developer who understood what I was doing and let me know there was a better way. That motivated me to start developing my own software design patterns and principles. The strategy I developed helped me to understand the software design patterns available in the literature and to make my peace with the often confusing plethora of patterns available to software designers.
Discovering your own software design patterns is an important skill, which we forget to learn when we force ourselves to learn patterns developed by others. In this article, I will share how you can develop your personal arsenal of patterns, while continuing to learn patterns already developed by experts and senior programmers.
What Is a Software Design Pattern?
A pattern is a guideline or step-by-step instruction to address a recurring problem. The problem can be in any domain, and it is not restricted to the programming world.
Though you probably understand the basics of design patterns, in our discussion we’ll consider the following three features of software design patterns:
1) The recurring problem
2) Steps to solve/avoid the problem
3) Common names or vocabulary
The focus of this article will be the first two features.
Everyday Examples of Patterns and Principles
We use patterns whenever we commute home after work. For example, I avoid going home between 5pm and 7pm. This is because it’s the peak traffic time, and I know from past experience that I will waste about a half hour in traffic.
In this example, the recurring problem is the traffic conditions between 5pm and 7pm. It is a recurring problem, as it happens every working day. My solution is to avoid going during the peak traffic times. I always try to get off from work at 4pm. If that is not possible, I leave the office after 7pm. Therefore, I have a guideline for a recurring problem that I face during my work life.
As you can see from this simple example, recurring problems and solutions are part of all of our lives.
I have been involved in the integration and testing of numerous systems. One solution to a recurring problem during integration and testing is to follow a sequence. If you don’t follow a particular sequence during integration, then it is quite possible that the system you’re integrating will damage the other systems you’re connecting it to.
To solve this problem we use a checklist. A checklist outlines the steps and the order in which they need to be performed. A checklist for a particular system integration allows me and other team members to follow a sequence during integration.
From this example, it is clear that you don’t necessarily need to refer to a handbook to look for best practices. People in your organization may have developed a solution for their recurring problem, as in the case of our checklist, which is developed by senior engineers. These are local patterns developed by our seniors or ourselves that you will not find in any textbook.
Hence in any field around you where there is a recurring problem, either you have to develop a solution for it (if the problem is related to you), or someone else may already have developed a solution for that problem.
How I Developed My Programming Patterns
In my current position, I acquire data, process that data, and produce graphs or files that explain how the data works.
Data acquisition can be challenging. There are many formats that data can come in, and each scenario presents different challenges including latency, data rate, and multiple streams of data, to name only a few.
To address these recurring challenges and problems, I developed a solution, which I called the Data Acquisition Library. I keep this library in a separate folder and whenever I am developing, I pull up the library and use the information it contains.
If you took a look at this library, you would find that it is just a bunch of classes of code. I write code in certain classes (usually the Device class if I am dealing with a new system or a new interface), and I am able to develop software quickly, which can be extended or changed according to variable requirements.
My solution to recurring data acquisition problems is an example of a pattern.
Another example of pattern creation comes from a web developer who is a friend of mine. He keeps code snippets in a file. This file contains short C# code snippets for each control that you can use in a web app, and a short description of a situation where that control works best. If I asked him to help me with a control, he’d open that file, see how to use a given control, and then let me know how to proceed.
You may be wondering why he doesn’t just use the MSDN. MSDN is useful, but it mostly provides generic help and only gives you syntax information. My friend’s snippet file is developed from personal experience and helps us solve specific problems that we often face. I face recurring problems with web app programing, but my friend and his file provide me with a solution; thus, I have another pattern that helps me design software.
It’s quite possible that you have developed some principles, guidelines, rules of thumb, and checklists for your own workplace. It’s also possible that someone else like a senior developer has created such tools for you.
My advice to you is that before moving on to documented software design patterns (e.g. GOF patterns) you first focus on your own home-grown software design patterns. If you don’t have them right now, then start developing them, even if you are a student or a junior developer.
How to Develop Your Own Patterns — Even If You Are a Beginner
Keep a Log Journal
For years I have maintained a log where I put my observations, ideas, or anything that I feel is important. I put a date on a sheet of paper and then write the entries for that day (and sometimes I keep multiple days on a single sheet of paper). This typically takes 5 to 10 minutes daily and hardly ever any longer than that.
Sometimes I miss my entry for a day or a couple of days. That isn’t a big deal to me because I can make it up later by writing anything I can remember for the missed day. I suggest you do the same. In a couple of months you will see around 40 entries in your journal, and that is good enough to start detecting patterns.
This is the first step in recognizing the problems you face in your day-to-day job responsibilities. The entries made in your log will help you identify patterns of problems when you do your reviews. In addition to that, maintaining a log will help you identify your productive days and the type of tasks and skills you are good at.
Once you identify your strong areas, you can utilize them more to be super productive. Writing a log is the single most effective technique that I wish I had known earlier, and it has helped me to be more productive.
What to Write in Your Journal
People are usually confused about what to write in their journal, or they want to make everything perfect from the start. It doesn’t have to be perfect. You just have to be consistent enough to make regular entries.
If you see a challenging problem, write about that. If there is an error or bug in your code that you caught recently, then write it down. If you see how a team has debugged and tested something, and you find it interesting, write about it.
If you still don’t know what to write, then check out tip number five in this article. Kayleigh has a great take on maintaining your log register.
Review Your Journal
The next step is to review your journal. I do a comprehensive review of my log journal quarterly. I look for repeating problems, the steps that I have taken to solve them, and then I document them in a file.
With the help of a log journal and quarterly reviews, you can easily come up with a handful of patterns that are yours, and, if you want, you can share them with your colleagues.
This method is very efficient for junior developers who have little or no software development experience. Senior developers can open their old projects and look for recurring problems that they have solved earlier and then document them.
Usually, senior developers have their patterns in their head, and they can write them down from memory and share them with their colleagues.
For students, you can maintain a log register and reflect about the class assignment or programming project in which you are currently involved or have completed in the past. If you want to learn exponentially and you are not involved in any programming project, you should get involved as soon as possible. Here is a great article by Latish on involving yourself in a side programming project.
From Private Patterns to Public Patterns
After you have developed your own repository of software patterns and practices (don’t worry if it’s small), you should check out the design principles and patterns of others.
This way, you will become more comfortable using those patterns in your programs. You will not only remember those patterns but also apply them in your own programs without much difficulty. This is because, by developing your own patterns, you have already developed competency in identifying the recurring problem and applying solutions.
Let me share a personal example with you. I have a rule of thumb that dictates that I create another class if a change in one class causes changes in certain variables and/or methods.
For example, if a class has three variables and any change in the code causes only two particular variables to change independently of the third variable, then there is a problem. The solution to the problem is: I have to create another class which consists of those two variables. This practice, or pattern, helps me write modular code.
After using this pattern for some time, I read a book called Refactoring: Improving the Design of Existing Code by Martin Fowler, a benchmark to improve software design. A very similar rule exists in that book as a guideline to improve the design of your code.
He described a problem very similar to mine and called it “divergent change“ ( he refers to problems as “bad smells” in code), and he outlines a solution that involves the creation of an “extract class,” which is similar to my solution. It was extremely gratifying to see my pattern recommended in such an important work.
While reading that book, I was able to quickly understand how to relate the “bad smells” Fowler identified to the “bad smells” I already had a solution for.
For example, it took me minutes to understand “Shotgun Surgery” and “Large Class” bad smells (read the book to learn what these are), and it took one week to implement them in a project on which I was working.
The point is, because I am used to identifying patterns in my own software design practice, I am able to more easily understand the patterns used by other designers.
It will be super easy for you to learn software design patterns if you start learning by recognizing your own software patterns.
What Patterns Will You Discover?
In conclusion, I ask for you to not try too hard with the documented software design patterns (especially when you are starting). We use patterns all the time in our daily lives, and you should focus on these first. The key to identifying our own patterns is to reflect upon our daily experiences, and for that, keeping a log is a very good tool.
Identifying your own patterns will not only enhance your knowledge, but through this practice you will also develop the competency to intelligently learn and apply the patterns that have been developed by other experts.
I would love to read about your design patterns. No matter how small or useless it seems to you, if it solves your problem, then maybe it will solve someone else’s problems, too.
If you are already maintaining a repository of personal patterns, then share your two best patterns in the comments below. Start a dialogue with some of your peers to see if your pattern is similar to theirs, and get a discussion going.