Occams Razor Occamality

Summary: Occamality and Software Architecture

This is a summary of my posts on the single most important principle of software: Occamality (non-redundancy). This principle applies to everything from the simple concept of what makes a piece of software "good" to developing and evolving software quickly, efficiently and with high quality. It drives good software architecture and all other aspects of development, from requirements through QA. 

This summary also includes my posts on software architecture, mostly explaining why widely accepted architectures like microservices are terrible.


To start, it's worth pointing out that software people don't know what makes a piece of software "good."


Software people often have strong thoughts about software languages and architecture. However, it is extremely rare for those opinions to be grounded in or related to the goals of software architecture. What are the goals? Here’s my proposal.


Here are the key specific things you do to accomplish the goals.


Here is a layman's, common-sense explanation of the same idea:


Here is a specific explanation explaining why Occamal programs are better than non-Occamal ones and why you should care.


How do you apply Occamality in practice? Here is a short, simple list of the practical things you do.


Occamality isn't another entrant in the myriad of design principles competing for attention in the chaotic world of software -- it's an overriding principle, one that stands above and ranks all the contenders.


Occamality isn't confined to writing software. It applies to all stages of the development lifecycle, from requirements through QA and support.


The value of reducing redundancy isn't confined to software; it's a general principle.


Saying that you should reduce redundancy in a program sounds simple, but once you get past trivial examples, it's not. Here's an analysis of the increasingly sophisticated kinds of redundancy in programs that should be addressed.


Reducing redundancy is accomplished by taking a declarative approach to programming instead of a purely imperative one. There are many examples of this.


Databases are an excellent, proven example of applying the principle of Occamality.


It's not just databases -- Occamality is a thread that weaves through much of the history of software.


You might think that reducing redundancy is an obviously valuable thing to do. The trouble is, modern software orthodoxy endorses the notion of collections of code that are separated by high walls (components, services, layers, objects, etc.), which typically leads to huge amounts of redundancy.


There is a simple idea that shows the basic approach to eliminating redundancy in programs: instead of stating how a thing should be accomplished, you concentrate on defining what is to be accomplished.


The optimal way to reduce redundancy includes recognizing that in addition to instructions and data, programs include varying amounts of metadata. Metadata is an easy concept for those who use it, but many programmers don't get past the idea of parameters. Here's a way to understand metadata:


In broader context, here's how metadata fits into a whole program, as the third dimension of software architecture.


For all dimensions, lack of redundancy is the main virtue. As a group, the more functionality is expressed in metadata and the less in code, the better.

A focus on metadata is similar to having a generic direction-generating program that refers to an easily-changed map.


Here’s more theoretical depth on the role of metadata in a software system, with a comparison to theories of the solar system.


Why put as much application knowledge into metadata as possible? It's the easiest thing to change, and above all, it's the best place to eliminate redundancy, which is the enemy of fast, error-free change.


Here is a more extensive explanation of the history and context of Occam's Razor and its relevance to software.


How do you achieve this ideal architecture for a body of code? Not all at once! You avoid the usual nightmare of useless, ever-changing requirements and do something that makes a customer happier than they were. Then fix it. Here’s the process, to which I’ve given a fancy name.


Here’s another statement of the basic idea:



Here is more detail and explanation of how to use increasing amounts of metadata to help build applications quickly, which of course should be a major goal of software architecture.


Here's a short case study from early in my career that demonstrated to me the incredible value of taking an Occamal approach to building an end-user business application.


Here is a more recent case study of a system based on extensive use of metadata and what happened when technology-fashion-driven executives took over the company.


One of the most basic aspects of software architecture is the data and where it is stored. The default choice for most architecture is to use a standard DBMS. Given the steady advance of Moore's Law, this is often no longer the best choice.



Bad Software Architectures

Software is infected with architectural religions, none of them with a sound basis in logic or real-world experience. It’s not that you can’t build software that sort of eventually kinda works with them – but it’s like building a car with a steam engine.

Sadly, some programming languages and programming concepts encourage redundancy.


Starting a couple decades ago the idea of “distributed computing” as an architecture become the thing all the cool kids gravitated to.


A modern incarnation (with a new name and rhetoric of course) is micro-services, which is supposed to boost programmer productivity.


Not only does micro-services boost programmer productivity, it supposedly is a “scalable” architecture – in sharp contrast to the evil “monolithic” architecture … a word which is usually pronounced with a sneer.


The trouble is, microservices make about as much sense as blood-letting did in medicine. It's widely accepted as useful, but entirely without evidence.


Programmers seem to like to layer their software, often without thinking about it.


Similarly when they link together pieces, a key decision is whether the coupling is loose or tight.


Components and layers have been promoted for a long time.




For the best results, it’s good to focus on the goals of software architecture described above, and assure that everything that you do contributes to those goals. Part of how you do this is to avoid the always-present temptation of following software fashions.