When I first learned computer programming, I thought I was a fine computer programmer. I produced much code that kind of worked; but looking back on it now I realize that the quality could have been much better. One of the important ideas I have learned since then is separation of concerns.
"We can solve any problem by introducing an extra level of indirection...except for the problem of too many levels of indirection." -Wheeler, et al.Separation of concerns is the idea that any program that is even a little bit complicated has more than one concern, and that code for each of those concerns should be kept separate in the program. For example, we might write a program that asks a person's name, remembers it, and greets the user back by name. The naive way I would have written this when I started out might have been:
- Create a variable to store a person's name
- Display a message requesting the person's name
- Wait until the user has finished entering input
- Move data from user input into the prepared variable
- Put together a message greeting the user, getting the name out of the variable
- Display the prepared message
That basic sequence might be called business logic. The problem is that real programs are a little more complicated than that basic sequence of business logic. Let's say the first version used an old fashioned text only UI (user interface). The complete program might look like this: (notice the additions in bold)
- Create a variable to store a person's name
- Use the text only UI to display a message requesting the person's name
- Use the text only UI to wait until the user has finished entering input
- Use the text only UI to move data from user input into the prepared variable
- Put together a message greeting the user, getting the name out of the variable
- Use the text only UI to display the prepared message
This starts to be repetitive, but it might still make some sense...until we need to upgrade it. Let's say we discovered that we can use a new graphical UI to display messages and receive input. Using the graphical UI would require different code from the text only UI. Now the new version of the program would need to be:
- Create a variable to store a person's name
- Use the graphical UI to display a message requesting the person's name
- Use the graphical UI to wait until the user has finished entering input
- Use the graphical UI to move data from user input into the prepared variable
- Put together a message greeting the user, getting the name out of the variable
- Use the graphical UI to display the prepared message
Now we have a problem. And, the bigger the program becomes, the bigger problem becomes. Every time we need to use a feature like the UI we need to repeat or copy and paste duplicate code to every area of the program we need to do the same thing. If we want to change the way we use that feature, we must make the same kind of change repeatedly in many different places. As I soon found out as a beginning programmer, that makes it easy to have all kinds of bugs. That is why we need separation of concerns.
In a program, a common reusable feature like the UI is a concern. Each area of code in the program should only have one concern; and each concern should only be dealt with in one area of the program. A program with proper separation of concerns might look more like this:
With Separation of Concerns:
- When using the UI,
- Version 1: use the text only UI
- Version 2: use the graphical UI
- Use this business logic:
- Create a variable to store a person's name
- Use the UI to display a message requesting the person's name
- Use the UI to wait until the user has finished entering input
- Use the UI to move data from user input into the prepared variable
- Put together a message greeting the user, getting the name out of the variable
- Use the UI to display the prepared message
As you can see, this code is more orderly compact, so if the actual code were very complicated, this arrangement might be easier to understand at a glance. Much smaller changes are required to upgrade from Version 1 to Version 2. This also makes the code much less likely to have bugs. User interfaces and business logic are only a few examples of many possible concerns that can benefit from separation.
However, separating software in this way is not always a good idea: if some code is already very simple and not likely to change, it might actually make it more complicated and therefore worse, to try to separate it into concerns. A good rule of thumb might be:
If you find yourself copying and pasting code, think twice and ask yourself whether this might be a good opportunity to improve the code by implementing separation of concerns.It made me a much better programmer when I learned to understand these ideas and use them in programming.
Comments
Post a Comment
You can use some HTML tags, such as <b>, <i>, and <a>.