Senior software engineer with 9+ years of experience. Eschew hype; focus on delivery and performance.

Living in Switzerland 🇨🇭 since 2017.

Clean Code(tm), SOLID, OOP, and Gangs of Four are not simple, by definition

Many will be triggered by the title, but that's all right, I'll lay out my argument.

"By definition" meaning if you look strictly at the definition of the words involved.

So let's do that.

The definition of simple

Looking at multiple dictionaries I find the following common definitions:

  1. easily understood or done; presenting no difficulty
  2. plain, basic, or uncomplicated in form, nature, or design; without much decoration or ornamentation
  3. composed of a single element; not compound.

And looking at the etymology (the root of the word, where it came from and how it came to be), from Etymonline.com I find the following:

The sense evolution is from the notion of "without parts" or "having few parts," hence "free from complexity or complication."

Link to the full etymology of "simple".

The definition of complex

In a similar guise, I find the following common definitions for complex:

  1. consisting of many different and connected parts
  2. not easy to analyse or understand; complicated or intricate

And looking at the etymology from Etymonline I find the following:

composed of interconnected parts, formed by a combination of simple things or elements

Link to the full etymology of "complex".

The argument

Looking at the above I hope my argument is self evident to anybody familiar with the real world code that Clean Code(tm), SOLID, OOP, and Gangs of Four adherents produce.

My argument is as follows.

Looking strictly at the definitions and etymologies.

Clean Code(tm), SOLID, OOP, and Gangs of Four by default violate definitions #2 and #3 of simple, and are in accordance with definition #1 of complex.

Definitions #1 of simple and #2 of complex are arguable. But I think you know what side of the fence I'm on.

These methodologies actively encourage complex and intricate configurations of software concepts in order to fulfill business needs, real or imaginary.

Particularly let's focus on the following concepts:

Object-oriented Programming

In its strictest sense, programming oriented around objects. Objects (normally defined by classes) are meant to represent a real world equivalent as a structure in code.

OOP encourages data definitions, behaviour definition, and execution, to be spread all over the place.

By definition that is complex, and is not simple.

Naturally one can argue that that is up to the programmer. But paradigms carry cultures with them, and OOP has this complex culture.

Clean Code(tm)

I'm careful to say Clean Code(tm) and not clean code. Robert C. Martin pushes a very particular kind of code as Clean Code(tm) and then says "that's your definition of clean code" when you make a valid point against it.

If you seriously follow his rules, your code ends up being hell to 1) find out where anything actually happens, and 2) keep in mind what actually is happening and where you are in the logic at any given moment.

Just as one example, the practice of "small functions, no bigger than 5-10 lines of code" causes you to write 5 functions for one business logic operation. Causing you to jump around to 5 different spots just to know what is actually happening.

By definition that is complex, and is not simple.

Many will argue that it also has good parts. That's OK, but the good parts are universally just "good advice", and not at all unique to Clean Code(tm).

Sidenote: If you want an example of what Clean Code (the book) should have been, take a look at The Art of Readable Code by Dustin Boswell & Trevor Foucher.

Gangs of Four (GoF)

The Gangs of Four are a collection of "set ways to solve set problems", a collection of patterns for OOP languages.

Often however the problem is poorly defined while the solution is well defined. Leading to them being an inflexible set of solutions to an infinite array of problems.

It introduces a situation where to "properly solve" a problem, you have to do it in the "standard GoF pattern", which are normally ill fit for the problem at hand.

Their solutions, being heavy on OOP, involve lots of classes, inheritance, and behaviour being spread across multiple files and functions.

In addition you must be familiar with the GoF pattern being used in order to understand the cryptic and often unintuitive naming, and hopefully have some guide as to what mess the programmer implemented in order to adhere to a predefined solution for an ill defined problem.

By definition that is complex, and is not simple.

Sidenote: If you want to read more about patterns and what they were intended to be by the inventor of the modern concept, an architect, read the book Unresolved Forces by Richard Fabian. A long read but quite informative.

SOLID

This is perhaps the most innocent of these. It's a set of guidelines for how to design your classes. It is inextricably linked to OOP, therefore the best it can do is not be complex, with very careful application, a sprinkle of luck dust, and lots of work, it can perhaps be simple.

But let's look at just one of the things SOLID promotes, getter and setter methods.

To reach for a simple value from a class, that the codebase implemented for itself, and not for any library use, I MUST call a method. Even to access a value, I must go through a layer of indirection. Even to set that value, even if it's a plain value, I MUST call a method.

By definition that is more complex than it is simple.

"But what if in the future you need to add logic" then you rename the property to have the classic _ prefix and your compiler will now let you know of all the places where you need to do update the code to use the setter.

Gall's Law

A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.
— Gall's Law, from The Systems Bible (John Gall, 2002)

Further reading