I think that every sane developer agrees that the SOLID principles are good and useful and when the time comes, you should apply them… but in this blog post I will concentrate on the: when the time comes part.
The idea is that, in my opinion, applying the SOLID principles for every part of the code is premature optimization and instead of making your code more maintainable it will make it a rigid and unmaintainable mess. Optimizations doesn’t refer only to speed improvements but also to architectural improvements.
For example: hiding all dependencies behind interfaces is something that a lot of SOLID developers do. Why? Because they are preparing the code to be modular, testable and changeable, even though, they don’t really have multiple implementations for the interfaces yet. Also, they often change the if statements to strategy patterns even though, at that moment, the if statement is small and really readable and will probably remain like that for a long time. Changes like this will split the logic in multiple files, when you want to read the condition you will need to check 3 classes instead of a few lines in a single file, in short, it will make your code more complex that it needs to be.
In my opinion this is wrong. It’s like having a piece of hardware, a computer, with all parts interchangeable, movable: it simply doesn’t scale. It’s OK for your RAM pieces, HDD and other components to be movable, but these individual components are not modular at all. You can’t change the pieces inside your CPU or RAM chip and most components on the Motherboard are glued to that plastic… otherwise it would be painfully slow or impossible to assemble a working PC. Look inside your Mac Book!, it’s modular till a point, but some components are not modifiable or movable! This is an absolute requirement for a stable and robust architecture.
Some parts of your applications should be modular and accessed via interfaces, but not all of them. As in any other engineering field, sadly, you can’t blindly follow some rules and expect to obtain a good design. You must sit down, analyze the requirements and apply some principles when needed and constantly adapt the design to the new requirements. No premature optimizations regarding the design will help you avoid the constant need for refactoring and redesign.
Don’t forget SOLID are not programming rules but programming principles, you can and should apply them, but when the time comes, do it softly… gently...