Things I learnt in “Programming School” — Computer Software layers

Fig 1. — An example of a layered software system

I’ve been writing code and developing computer software since I was 18 years old. Now I know that some of you might say “That’s nothing! I’ve been programming since I was six!”, well, good for you. Considering that I am 50 this year and that my programming career started in Nigeria where computers were a very rare commodity, 18 was early and I think I have done well.

So after 32 years of “Programming School”, I’ve been looking back at what I’ve learned over the years and thought I’d share some of it with whoever cares to listen. These aren’t my memoirs, but are probably the closest I’ll get to writing any. I’ll start with this article on my basic-level take on how computer software works, and then we’ll see where it goes from here.

One thing that stands out to me about modern software is how much of it is hidden below the surface, and the more the years pass, the more that gets hidden. Good software, of course, is the one that hides its complexity the best; the easier it is for the user, the harder it has been for the developer! But, under the covers, any software system, no matter how complex, is simply a number of layers one on top of, or wrapped around, the other; the best programmers simply know how to make the best use of the appropriate layer at the appropriate time to perform the appropriate task.

Any software system is simply a number of layers one on top of, or wrapped around, the other

How deep does it go?

Let’s take a simple (or apparently simple) example…what happens when you press the “A” key on the keyboard in a standard textbox in a GUI (Graphical User Interface) application?

Here’s how the layers stack up:

Fig. 2 — What happens (roughly) when a key is pressed on a keyboard

Let’s take the “Keyboard Software Layer”, as an example, and break it down a bit…

Fig. 3 — Keyboard Software Layer

Now, if I happened to be a keyboard manufacturer, I could probably break Fig. 3 down even further, but you get the idea. In this case, if I was interested in flashing the Caps Lock LED on the keyboard anytime a key was pressed, I can ignore virtually every other thing that the computer is doing and concentrate on figuring out the “Toggle any LEDs on the keyboard if appropriate” layer. On the other hand, if I wanted to do this only when the “A” key was pressed, then I would probably want to start at the first layer…“What key was pressed?”

If we take the “Operating System’s Input Processing Layer” (from Fig. 2) as another example, it could loosely be broken down as…

Fig. 4 — OS Input Processing Layer

Which layer would you concentrate on if you wanted to ensure that only one running program on the computer knew about a particular key press? The middle one? I think I would start there too.

Sounds simple

It really is as simple as that at the fundamental level. The complexity arises in first tracking down the layer you’re interested in, or that you need to modify, and then discovering that it was poorly written, has undocumented dependencies on ten or even fifty other layers, or was originally written in some arcane language such as Assembly (! Or perhaps it is hardwired to some hardware component manufactured by a company that’s no longer in business, or even that the software is so old that all the original developers are either retired or deceased!

In these scenarios, received wisdom dictates that you create your own layer! You may need to create it above existing layers, below them or even around them. After many years of software development, I’ve seen some software layers that resemble a sandwich (a very big sandwich). I’ve seen some software resemble an onion (some big, some small). Yet others are a combination of both, …, and then there are others that look like neural networks! But that’s a discussion for another day.

The more things change, the more they remain the same.

In my early programming years, if I needed an ISAM (Indexed Sequential Access Method) file, I wrote the ISAM routines myself (In BASICA in those days). Eventually ISAM file routines became just another hidden (taken for granted) layer in most modern database systems.

When I needed to restrict input on the screen to well defined fields that you could tab through, insert text into, constrain to accept only numeric input, etc., I wrote a field-painter layer. Today, field-painter logic is just another layer hidden deep in the bowels of all operating systems, and all modern desktop and mobile apps are yet another layer on top of these routines.

Incidentally, constraining a field to accept only numeric input, is still a popular question with developers to this day. Apparently, the more things change, the more they remain the same. Here are a few questions I found about this very thing on Stack Overflow:

So my philosophy when dealing with any software problem is this: find the relevant layer, change it, replace it or put a wrapper around it, then move on…if you try to figure out how every layer works, you’ll never get any real work done; you’ll know a lot of course, but will probably be of no practical use as a developer in the real world.

Perhaps I’ll need to change this philosophy when I have to deal with my first neural network, but I’ll cross that layer when I get to it.

I fully admit that there are difficulties with this simplistic approach to viewing software but I find that it is a very good starting point that works for me and I then deal with any exceptions to the rule as they arise.

Just one of the things I learnt in “Programming School”.