Bad Code Scales But Bad Abstraction Does Not
2025-12-15 20:25Bad code that is properly encapsulated can be contained and managed.
Bad abstraction will bleed into everything and contaminate everything it touches.
I think the simple concept of Coupling and Cohesion is one of the most important and surpassingly often overlooked concept of software engineering. Low coupling and high cohesion should be simple. Obviously it is not. It is one of those things that simply work or will have you spend hours refactoring something that is suppose to be easy.
You will lower the blast radius by properly isolating a system, package, or whatever conceptual separation you are using, by simply setting clear boundaries for what it should contain.
Oh, premature optimization you say?
Nah. A popular Go development idiom to "start out with a main file and take it from there" is by no means an opposing idea. It is not an argument to be made for skipping proper abstractions. It is not even necessarily more work. Perhaps blast radius is the wrong term, but when you find yourself digging around in six microservices in order to refactor some domain object you will curse the same Gods.
I recently found myself refactoring a database integration in a Python project. A handful of smaller projects in a mono repo. No big deal. My predecessor had opted for using Snowflake as an OLTP database. Not a performant system by any standard. Needless to say, both latency and throughput struggled with keeping up with the performance requirements. Some request where in the two digit second range. Granted, not the best decision given the nature of an OLAP database. At the same time this particular organization favor a speedy time to market (TTM), so an argument could be made for a reasonable decision given the circumstances. The system delivered value, and in the end that is all that matters.
Anyway, looking at the database integration one could expect some kind of abstraction between the database and the application. I am primarily thinking of a repository aimed to decouple Snowflake proprietary code from the application. Furthermore, one could also expect some shared package since these applications loosely followed the same basic CRUD interaction patterns. No such luck.
Instead, I found duplicated code for database interaction in all sub projects. Not your typical copy-paste, but unique implementations everywhere. Most of it hard coded SQL queries aside from one attempt at a data access layer. In such situations it is obviously tempting to just rip it up and start over. To be honest, it was tempting, but in the absence of testing, performing a heart transplantation on a living patient would probably stretch my luck. I have always found testing to be the best tool to implicitly introduce proper abstraction to any system with minimal effort.
If you can't test your code you have almost always messed up your abstractions.