Growing code: It’s all about cohesion

Tristian Barrett
Creating TotallyMoney
4 min readJun 23, 2023
Abstract art with circles and shading and connecting lines

At first there was GOTO, and everything was good.

But then codebases became larger. The code became a jumble. There was a need for more cohesion.

So smart people sat around and invented the idea of functions! (or sub-routines as they were called back then)

And everything was good once again. People could reason about how programs worked. Functions kept things cohesive and reduced coupling.

But people kept using GOTO, and so everything was not good.

And so smart people said: “Go To statement considered harmful” and they invented structured programming, and we had systems for using while loops, and if statements and lots of other fun tools.

And everything was good once again. People could reason about how programs worked. Structured Programming kept things cohesive and reduced coupling.

But programs continued to get larger and larger and even functions reached their limits. Programs were doing so much it became hard to collaborate with other people and reason about what each part was doing.

And so smart people found a solution. Modules. If we wanted to operate with files, we’d find our function in the File module. If we wanted to create a graphics function, we’d add it to the Graphics module.

And everything was good once again. Related things were together, and unrelated things were separated. There was higher cohesion and lower coupling.

But programs continued to get larger and larger, and modules could only help so much with the data that was being passed around willy-nilly from one part of the program to another. It became hard to reason about what parts of a program were responsible for what data.

And once again smart people found a solution. They saw what other smart people had created for developing simulations and figured that it would be a great fit for the problems they were facing, and Object-Oriented programming entered the mainstream. Data structures and the functions that operated on them were kept together in objects.

And everything was good once again. We could now reason about what code was responsible for what data and vice-versa. There was higher cohesion and lower coupling.

But programs continued to get larger and larger and object oriented programs had their own problems, such as Ravioli Code. It became hard to reason about how all the objects were interconnected to each other, and what was changing what.

So once again smart people got together and came up with N-Tiered architecture. The presentation layer got separated from the business layer, which in turn got separated from the data layer.

And everything was good once again. We could now reason about what caused the UI to change, and what caused the data in the DB to change. There was higher cohesion and lower coupling. And we now had specialization — Front-End and Back-End developers (though it would take a few years for those terms to appear).

But programs continued to get larger and larger and separating OO programs into tiers only did so much to fix things. Within each tier It became hard to reason about how all the objects were interconnected to each other.

And once again a smart person (Eric Evans) came up with a solution. Domain Driven Design. Aggregate roots bundled several objects together, and Bounded contexts bundled aggregate roots together. Then other patterns such as repositories and services helped by knowing where to put things.

And everything was good once again. We could now reason about what parts of the system were responsible for what parts of the business. There was higher cohesion and lower coupling.

But while DDD was doing wonders for the domain and data layers, it did nothing to help with the presentation layer, which was becoming larger and more complex and undergoing constant change.

And once again smart people came up with React and Redux and similar technologies. User actions became separate from state changes which were separated from rendering.

And everything was good once again. We could now reason about state, actions, and rendering independently. There was higher cohesion and lower coupling.

Note: all the above didn’t happen in a strict chronological order. A lot of these advancements were being made at the same time, and being shared unevenly amongst the community. There’s also a lot more things I could have added, but I think you get the drift.

I don’t know what innovations will happen next in the world of software development, but I’m sure one of them will involve improving cohesion & reducing coupling. Complexity is a beast, and it’s not going to go away. It’s going to continue to grow and create new and wonderful problems.

Our systems keep getting bigger and more complex, but our brains aren’t getting smarter.

Our organisations keep getting larger, but our communication isn’t happening much more effectively.

Yes, we try to remove complexity and make things simpler, but there’s an essential complexity to the problems we solve that can’t simply be swept under the carpet. When it comes to dealing with that essential complexity, finding ways to improve the cohesion of our code is the solution that’s stood the test of time.

I’ll finish with a link to one video that I feel does a wonderful job of demonstrating how to take highly coupled code and go through a process of getting to highly cohesive code: Sandi Metz’s, “All the Little Things” presentation. It’s well worth a watch if you’re interested in refactoring, OO code, or just making code better in general.

--

--