Programming Fundamentals Part 5: Separation of Concerns (Software Architecture)
By: Ryan Michael Kay
Tags: Software Development, Kotlin, Software Architecture, Android, Programming

This article series is based on rough drafts of what I intend to eventually turn into a series of lectures and course ware for my brogrammers and siscripters out there. Feedback is welcome, and if it proves useful, I would be happy to list you as a contributor.

2020 UPDATE: I have put together a course for Java which introduces the concepts I have described in these articles, but in greater depth and clarity. If you like my writing, I think you will love my video lectures:

Working Class Java: A Beginner’s Guide To OOP & Software Architecture Udemy Link| Skillshare Link w/ Free Trial

Contents

I would like to thank my friend and brogrammer Darel Bitsy (Medium: Darel Bitsy, Github: github.com/bitsydarel), for helping me to cement my understanding of separation of concerns. After several long discussion between us on the topic of Clean Software Architecture, it became quite evident to me that this quite possibly the most important principle to understand when it comes to designing and building programs.

In the previous article, my goal was to discuss the nature of Functions in Information Processing Systems (such as computers), and how there appear to be two primary distinctions of such Functions. With any luck, I did a decent job in explaining what these distinctions look like (along with some practical takeaways for error handling), but I did not go into any detail as to how one should go about keeping them separate; nor why I believe this is a very important thing to do.

In this article, I will not be discussing any particular facet of the three fundamental ingredients for any program (information stored in memory, computational logic, and control logic), but I will be discussing a principle which applies to all of the above; along with everything else. In fact, this principle is so powerful that I see it pop up regularly in just about everything I do, and have ever done.

With that in mind, I would encourage you to take a moment at the end of the article, to think about where you have, or could now, apply this principle in domains outside of programming. Connecting these concepts with familiar and simple analogies will help you to understand them greatly, and I will begin with one of the simplest analogies I could think of:

“Sidewalks” (or “Foot Paths” for those outside of NA). Do not worry, this will still help you write better programs.

Over-analyzing Everything Has Its Benefits

Some years ago, I was on my way to my job as a suit salesperson (I am not joking), and I found myself walking down a side-walk which had recently been replaced. While I am often at odds with the way in which my tax dollars are spent by the local government, this particular path was due for a replacement as it looked something like the picture below:

Now, as opposed to using one single continuous layer of asphalt or concrete, the replacement instead used a series of concrete squares, something like the picture below:

Being wired to ask questions from the most mundane to the most philosophical at all hours of the day (I am not bragging; it can be very annoying), I found myself briefly wondering what the benefit of separating a continuous sidewalk into sections might be:

Supposing that a section was to become cracked or destroyed, one would only need to replace a single section to restore the sidewalk to its former shape and function

One could build each segment of the sidewalk in isolation of the others

I will not carry this analogy further, but I would like you to keep it in mind as we now move to a more technical exposition of separation of concerns.

“Everything is teaching us.” — Teaching of Ajahn Chah

Separations In Graphical User Interface Applications

Several years ago, I set out to overview all of the different GUI architectural patterns which seemed to be popular (MVC, MVP, MVVM), with the intention of understanding what was similar and dissimilar between them. I naively expected everyone to share the same definitions of these different patterns (I hate to burst anyone’s bubble, but this is sadly not the case at all), and quickly became frustrated with all of the different articles and open source code bases I was pouring over.

If you would like a summary of what I have learned about software architecture over the years, check out: “The Perfect Model-View-Whatever Architecture.”

Eventually, I started to piece together that the common thread in most of these architectures (although plenty of programmers contradicted this idea), was a separation of three kinds of code:

User Interface/View: Code which interacts with what the user sees, and can interact with

Code which interacts with what the user sees, and can interact with Logic: Code which handles events and coordinates the flow of data between various parts of the program

Code which handles events and coordinates the flow of data between various parts of the program Data/Model: Code which is primarily concerned with storage and retrieval of real-world information (which I will refer to as “data” from here on)

With the exception of MVVM, where the term View-Model implies something to do with User interface and Data, yet is often filled with logic (I am not saying it is a bad pattern, but it is an atrociously bad name based on how most people use it), these three distinctions correlate fairly well to most three-layer architectures. For quite a long time, I referred to my architecture as Model-View-Presenter, but a turning point for my naming conventions was when another developer exclaimed that my architecture “looks a lot like Model-View-Controller.”

My first thought was that this confused onlooker needed to be educated on the subject of GUI architectures, but as I once again took a hard look at the differences between the two patterns, I became less enthusiastic about arguing the point. In fact, after learning that MVC has meant many different things over the years (originally coined by Trygve Reenskaug), I finally decided that the only solution was to start using the words I thought best described my architecture instead.

My goal in doing so, and in discussing them in this article, is not to get you to start using my words, as that will only confuse the issue further. However, please pay close attention to the underlying concepts behind the words; which I do believe my words may do a better job of pointing therein.