Any problem in computer science can be solved with another layer of indirection.
This is a saying that I’ve heard a lot in my career as a software developer. But, I’ve come to realize that it can also be a source of a lot of problems. Just because you can add a layer of indirection, doesn’t mean you should. Lately I’ve been saying “any code can be complicated with another layer of indirection.”
Over-engineering can be a big problem in software development. Sure – you can add a layer to abstract away the database; you can use dependency injection to make sure all your components are pluggable; you can make an interface for a class, just in case there will be a second implementation at some point. But, you have to stop and weigh the consequences of these decisions. Every decision you make is a trade off. You gain something, but you also lose something. In the case of over-engineering you lose simplicity. The code becomes more complex and harder to read, so it becomes harder to understand, maintain and debug. Do you really need that extra layer in your software?
I did a quick Google search and found that there was more to the original quote. David Wheeler actually said:
Any problem in computer science can be solved with another layer of indirection. But that usually will create another problem.
That second sentence is something I have never heard quoted before, but from now on whenever I hear someone say the first part, I will point out the second part of the quote as well.