SOLID Software Engineering Principles
Back in 2009, the StackOverflow podcast #39, Joel Spolsky started openly bashing the SOLID principles and TDD (Test Driven Development) and claims they were put together by someone who doesn't really write a lot of code.
This made me a bit upset.
I listened through the Hanselminutes podcast in question and what I heard was quite different from what I think Joel heard because Joel went on about the adverse effect of writing unit tests, that it's, probably time better spent doing something else, and the absurdity of turning everything into an interface.
I think this story is really interesting, and Joel actually invites Robert Martin (Uncle Bob) to the show, after he published an open letter to Joel and Jeff, which became the topic of podcast #41. And Joel starts the podcast by apologizing.
Experienced software engineers realize when they are wrong.
But it's important to point out that Joel is also right, in that he creates a situation where you have a programmer that's at 99% code coverage and then presented with three choices:
- Get to 100% code coverage
- Deliver a key feature to a key customer
- Dramatically improve usability
Only one of the above choices is wrong.
At this point I'm 50 minutes in to the follow up podcast and I'm quite confident that they won't actually be addressing the core issues. Joel has been going on and on about GUI testing and how unfruitful that is. And I'm tired of examples in which he appears to be trying to test layout quirks rather than stuff that matters.
It feels as if the whole discussion was geared towards using SOLID and TDD where it's not appropriate and it's unfortunate because they effectively fail to highlight the importance of SOLID software engineering principles.
The Pragmatic Programmer is a great read, but I think the key takeaway for any such book, is that as a programmer you should be pragmatic.
To answer the question, why SOLID and TDD? You only need take a look at the real world and make a simple observation.
What SOLID is all about is understanding the underpinnings of SOLID software engineering principles. Why modular code better responds to change and how you avoid friction while adhering to principal object-oriented design practices. It's a lot of fancy wording to say that you can design code to not be tightly coupled and still deliver on schedule, all while quickly adapting to change in the real world.
I did say object-oriented, but actually SOLID has very little to do with object-oriented programming, it fits very well into any paradigm, because it's good advice and you're not a SOLID zombie, just because you care about system wide interactions.
Now, I tend to forget that the minds of people all work differently and don't typically share the same history. I often argue my point without realizing that people might not understand where I'm coming from. So, I'd like to drive this home with, why I value, the SOLID principles.
Why SOLID designs matters
This all started with me trying to get into the habit of writing tests. I slowly realized that I couldn't test my code effectively because the implementation was in most cases tightly coupled. There was simply no way for me to pull out the important parts and isolate them in a controlled manner, and then run meaningful tests. At the time I couldn't motiviate why I had to put up with the additional work.
To enable the above scenario I had to learn new principles and through practice and hardship I eventually got to understand the SOLID principles. With that came a new understanding and in hindsight I was already using tests to test my code just not in a very structured way.
The point of doing SOLID is that you're gearing up to be testable by design. But to accept SOLID you don't have to accept the entirety of TDD, you simply have to acknowledge that there's value in being able to do automatic testing, something which you cannot do if you don't design for it.
Testing is a way to drive SOLID designs, which is one way to tackle the constant change we have to deal with every day.