Hello World

How to Build Boring but Alright Software

2021-11-23programmingmodularitydesigninheritancecomposition

The title explains everything this article is about :)


Create a Flexible Software

In software’s famous SOLID acronym we have ‘O’ for the open-closed principle: software should be open for extension and closed for modification. In architecture you should take a similar approach as software is constantly evolving, and growing. You cannot assume it will look anything like it does now in 5 years. And you must allow for this by not making assumptions as to what it will look like. I don’t really agree with the idea that software should be closed for modification. That is only bad if modification will break other reliant sections. It shouldn’t. Software should be closed for modification in the sense that one should not need to modify one section in order to fix another. Instead one module should be reliant on the behaviour of another. If some code will require modification of another module, you need to start considering where it should belong.

One way of doing this on the ground is by avoiding inheritance, and using composition as both the macro and micro scale. This is because inheritance always means you have to assume the future desired behaviour of the base code. Take the below example: it has the assumption that all mammals have legs and ears. But perhaps we didn’t do our research well enough - remember dolphins? Now what do we do? Do we have to modify every single inheritor of MammelBase to address this? This is a very over simplified example but it does provide a good illustration that inheritance relies on assumptions. One wrong assumption can have wide ranging effects on all inheritors and even those using the inheritors.

Micro Scale

At the macroscale we can also apply this principle. When building components for a system, don’t have common modules for behaviour. Common modules should in general be for utility code such as database access. In the diagram below you can see this issue illustrated. Whenever we have new code added into our system, we have constant new trickle down risk into any of the reliant code.

Macro Scale

Make it Modular

We want our software to be non-brittle and flexible. Modularity is a great way to achieve this. Take the diagram below of the two modules. Each module is responsible for its own logic leaving you, the programmer, the freedom to modify the module however you like without affecting any other modules it interacts with so long as you keep the behaviour contact the same. This is decoupling. We keep our flexibility for change within the modules. Another benefit is it is also easier for people to understand which leads to faster, more bug free development. The fewer classes in a module means fewer things for the person working on the module to comprehend. And as we well know, if things are simpler, they are easier. (Well for me anyway, and until we have AI programmers, probably for others too!)

Modular

Design for Simplicity and Convention

Got a wild idea? Probably you should bin it if you’re doing something normal. I don’t say this because I dislike wild ideas. Indeed we would be still living in caves or subsistence farming without wild ideas. (Sometimes I wonder who first thought of milking cows; it is weird, you have to admit). For most problems you’ll come across in your working life, there will be solutions available for you to use. There’s a reason there is such a plethora of books out there all with rather similar ideas about building software. The more I read, the more I feel I should save money and buy fewer books as they all seem to echo similar sentiments. (This is a tongue in cheek comment, please don’t judge me!).

The diagram below shows a pretty standard evolution of a software platform - not counting any other things a business might have going on like data pipelines. In stage one it’s still a small company and needs are more at getting everything up and running. No need to manage a lot of complexity yet. At stage two the business is growing, and likely the team two. It’s no longer feasible to have everything in one place - notice the growing modularity! By stage three we’ve entered into fun territory of full modularity and every service has its own database.

Platform Over time

Keeping somewhat to this recognised pattern is tried and tested. It also allows for anyone new to quickly pick up on how things work; in all likelihood they’ve seen something similar. We make code for other people, not for a computer. This is not to say this is the only way of developing code - I for one love new and crazy ways of doing things - but rather one should aim to follow convention and simplicity in most business scenarios.

A conclusion of sorts…

Building software is an art; there is no correct way to build it, there are just ways of making it beautiful. These items help with this by bringing order and symmetry. The one thing I think is the most important is modularity, however you implement it. It can be code units, microservices, or just smaller services. I firmly believe in modularity not least because it makes my life easier, but also because it allows for code that can quickly respond to business need: you can hire more people without having issues related to working in parallel, it is easier to understand as your brain has less to comprehend, and easier to deploy. What’s not to love?