The underlying principle of good software that nobody talks about
Whether you are a new developer, a senior systems administrator, or a product developer, there are many software development principles you have already heard or read about a lot; either, they are a part of every book on development, something thousands of tutorials have been written for, or something your company wiki lists as a good practice.
Universal truths in software development
We all have heard of them — be it the SOLID principles for writing good code; the agile principles for making more progress with cross-functional teams in sprints; the extreme programming principles like Continuous Integration; or others.
Once you hear of them, it’s hard to not always hear of them. Even though one may not have learned all the formal names and terms, they are wide-spread enough so that many can be considered common knowledge.
A universal secret?
However, there is one principle that fueled and still fuels most of the achievements of software design; a fundamental force in our every day to day work with software:
Things that change together should be placed together.
This is such a fundamental, always applicable principle that it deserves a lot more attention than it is getting, by anyone doing anything in IT. In comparison with the profound impact it has, it really feels like it’s being treated as top secret.
Just a few examples
If you are a developer, just think about the last time you had to write a unit test — which is hopefully not too long ago. Think back about your professors, books, or online tutorials you have used to learn to code, how did they structure unit tests?
Did they add a separate folder, maybe even in the root? And did you find yourself hopping through folder hierarchies much too often for almost every little change, making it hard to keep track of which scenario is testing which part of your code?
How about when you working with different layers for persistence/repositories, domain objects, frontend, services? Did your framework have different folders for those, and whenever you added a new feature, you ended up going through your full order hierarchy, and then when micro-services became all the rage, you noticed it’s really hard to now untangle your different services?
If you are in IT Operations, think about the most recent changes as well. Do you now place your dockerfiles near to the containers that they are describing, maybe in a DevOps fashion? Maybe even with terraform files? Did it help describing a service fully, whereas the past split-repositories approach felt like something needing a lot of manual orchestration?
Or, if you are in product development, did you notice how much more output the team achieved when teams were cross-functional and all integration work was the responsibility of the team? And then again, when customer feedback was given to the team responsible for making the features, instead of to a separate entity in your business?
DevOps, (micro-)services, micro-apps in the frontend, cross-functional teams, …; all of those examples show — whenever you keep things that change together close together, you gain a lot; and whenever you don’t, you make your life more difficult.
A few more examples from recent and not-so-recent developments:
- Agile culture — brought the people ideating on a product feature closer together with the people developing it; the people developing it closer together with the people testing it etc., similarly to
- DevOps culture — brought the team developing something closer together with the team shipping it
- Micro-services which even define their own storage
- Specs / unit tests close to components, rather than stand-alone parts
- React components and their store close to each other, or frontend micro-apps
- Dockerfiles or infrastructure code next to the service they are describing
We can predict that everything that isn’t yet aligned with this approach, will be, as teams get more autonomous and naturally will have more responsibility for the features they are developing.
This may result in BI no longer being an afterthought or a separate team; documentation and support finally becoming part of the agile teams that is building the products; database versioning getting better tooling, and much more — from the way we structure our code to the lengths we have to go through in our development and support processes.