Separation of Concerns

Continuing on my previous post about separation of code responsibilities where I was mostly just discussing one aspect of a book I appreciate, I now want to comment on the concept of separation of concerns. While thinking about this idea I realized that I've been a follower of this idea longer than I previously thought. I admit it, I don't separate my code as well as I often could.  I am sure that everyone reading this has heard that we should try to make things modular and that we should encapsulate pieces of our code. It is all part of what I consider to be classical education taught to programmers everywhere.

Separation helps for many reasons. It allows us to think about only the currently important section of code. We need not always be concerned with how everything else works. It is much easier to solve problems by implementing a solution that doesn't require at every step being concerned with the details. If I want to tell someone how to load boxes into a truck. I want to say something like this.

  1. Pick up a box
  2. Place the box in the bed of the truck
  3. Repeat previous steps until no boxes remain outside the truck

I don't want to have to do something like this.

  1. Pick up a box
    1. Move next to a box
    2. Bend knees so you're at about the same level as the box
    3. Put hands on the box
    4. Grip the box tightly
    5. Lift up using your knees
  2. Place the box in the bed of the truck
    1. Move while still gripping the box
    2. Walk over to the back of the truck
    3. Move box away from body and toward the truck
    4. Let bottom of box touch the truck bed
    5. Release grip on the box
    6. Move hands away from the box
  3. Repeat previous steps until no boxes remain outside the truck

I prefer to be able to assume that the person I am talking to knows the simple things. If I have to get into this kind of detail anytime I tell someone how to do something I am going to forget details along the way. I'm going to say something incorrectly. I also may mess up the overall algorithm because I am too concerned with the details of the steps. With different pieces being separated it makes it much easier to solve problems. There are plenty of other reasons to separate what we create.

SeparationOfConcernsAnother reason that it is nice to have our work separate out nicely is that we are able to replace and adjust sections of our work without having to rip it all apart. If I have been having sections of code performing plenty of different tasks then I make it a lot harder to change it. When I go to make a change I am dealing with a lot more than I need to be, because a lot more stuff is there. The benefits of this are plenty and I am sure people can suggest plenty more. (I am also sure there are plenty of reasons to not have modular code.)

As I am sure is the case for many developers reading this, I spent a lot of time working with Linux machines. One thing I of course noticed with the classic applications found in the open source world is the tendency to have individual programs perform one task. The output of one program is often passed as input into the next program.

One line I heard often is, "Why does program xyz need to sort its output? Just send it through program abc, because it sorts already." At first I think the idea of having a program for sorting is kind of silly. Isn't it easy to sort? Couldn't all of these programs just sort? Well even sorting text can be fairly complicated. Which algorithm should you use? Should sorting be on the first character or the second? Maybe we want to sort based on the second column of data. I don't want to go into the code for a large number of programs just to update how it sorts.

Along with separation of concerns comes the also very important need to break dependencies. When we perform this separation we are breaking things into separate objects, libraries, and who knows what else. Some dependencies aren't a big deal. Most of my applications are fairly dependent on the .NET Framework, but I am not concerned with this. If I am stopping using the .NET Framework, I am probably switching languages or something and rewriting anyway.

While thinking about how to break up responsibilities among sections of code I've really been noticing how great an idea those separate programs have always been in the Linux world. I've noticed a trend away from it, but the core applications still tend to follow that old principle. Keep things small and performing only one task. Need something else? Let another program handle that task. As any code attempts to do more, it just becomes more difficult to work with.

The idealistic purpose of computers is to make our lives easier. Try not to let them do the opposite.