Back in year 2000 I was running my own software development company and had a small kind of ERP system targeted at small companies.
Reading about all the advantages of interfaces such as the ability to switch implementations one for another at any time, I thought: "Wow! That’s amazing! I gotta do that!". So I went extracting the interfaces out of each class and making the classes refer to the interface. Soon I realized that in order to be really independent, I had also to change the methods and properties to point to the interfaces so I could change the object being passed to them.
Several weeks later I had it all done and working, but those were several weeks not adding new features. Only refactoring code at a time where we had no refactoring tools like today.
One could argue that I should have done interfaces from start and then I wouldn’t have had all that work. OK, I agree. The problem is that all that was new for me. Still, all the work would be compensated by the possibility of switching implementations whenever I needed!!!
The problem is that time never came! OK… To be fair, there were a couple of situations where I benefited from using interfaces. And that only became possible because I got a new insight, a new way of seeing the world – through interfaces. But for the most part, it was an overkill. When modifying a class, instead of having one place to change, now I had two!
It has been attributed to Albert Einstein that “Everything should be made as simple as possible, but no simpler”
After so many years of developing software I came to appreciate simple designs.
I think about the ways the code might evolve in the future and instead of putting in things that pave the way to this predicted future, I tend to leave out the things that would otherwise make it more difficult to get there.
The reason for this is that the predicted future may never come to realization. So by putting in stuff now, I would eventually be throwing resources away. Resources that may be needed for something else.
It gets even worse when – driven by real needs – you find yourself having to accommodate changes that go in another direction that eventually are incompatible with what was initially predicted.
All of this has already been explained by people much better with words than I am. Take a look at YAGNI, KISS and DRY.
The bottom line is: Grow you software simple. Only add complexity when really needed. Even then, try to keep it as simple as possible, but no simpler. 🙂