And it’s not just an underrated Moody Blues album
It’s been said that it’s important to write code for the maintainer, code that’s easy for a person to understand. It’s also been said that code should be decoupled and easy to change as requirements change. The problem is that these two goals are often in conflict.
One of the easiest ways to make code easy to understand is to make it very explicit. Make every decision and assignment in line. Maybe add some functions for readability, and so you can collapse the code in the IDE to it’s well chosen name. Don’t rely on anything else. And don’t use abstractions like interfaces and factories. Those just make it harder to find the code that’s running.
One of the easiest ways to make code easy to change is to abstract all the messy implementation details behind an interface. Then, when you need to support some new variant, you just update the factory and everything else is the same. Or use dependency injection so that your code doesn’t even know about the factory. The thing you need is just magically delivered on startup.
As you can see, there might be some tension between those two things. So how do you know what to do? As usual, it depends. It depends on where you are in the product cycle. It depends on what you know you’re going to need versus what you think you’re going to need. Because YAGNI.