This is the 41st episode of the StackOverflow podcast, where Joel and Jeff sit down with Robert Martin aka "Uncle Bob", and discuss software quality, the value of software engineering principles, and test-driven development.
Joel clarifies that some of his comments in Podcast #38 were a bit unintentionally ad-hominem, and apologizes to Uncle Bob for that -- see Bob's open letter blog post. But on the positive side, it did get us a podcast with Uncle Bob!
Increasing our servers from 4 GB (web) and 4 GB (database) to 8 GB and 24 GB, respectively, opened up tons of breathing room and unleashed a lot of latent performance. Memory is incredibly cheap right now; there's no reason not to install ridiculous amounts. It is (almost) free performance. Bob reminisces about when he bought memory by the bit!
When I said "quality doesn't matter", I didn't mean it literally. If you deliver a software product that nobody likes or wants to use, it doesn't matter how great the quality of your code is. You can always fix code quality -- but fixing "nobody gives a crap about our product" is far more difficult. That's what you should be worrying about most of all.
Quality has many dimensions. The cleanest code in the world could utterly miss the point on usability, scalability, performance, and meeting users' expectations.
On the other hand, as Bob points out, there are companies that have shipped broken products which permanently damaged their reputations and, in some cases, even forced themselves out of business.
Bob's SOLID principles are based on some well known conventions. I talked about the first one, the Single Responsibility Principle, in Curly's Law: Do One Thing. You may have heard this before as Don't Repeat Yourself (DRY), Once and Only Once, or Single Point of Truth.
We wonder if some of these guidelines -- such as "deploy independently" -- are obviated by the inevitable forward march of technology, such as software delivered through the cloud, and virtual machines.
What happens when principles fall into the hands of people who don't really know what they're doing? Or people who become bureaucrats, rigidly enforcing rules on everyone? We think the existence of rules, in and of itself, isn't necessarily a net good. The types of developers who need those rules are often immune to them.
Often, software developed internally doesn't have to be good; users are forced to use it. This software would never survive as a real product that had users who actually had to want to pay for and use the software. Bob is fond of asking "why is open source software so much better"; part of the reason is that this software has to survive in the real world on its own merits to garner users and attentions. It's not isolated on some peculiar little corporate Galapagos island where it has no competition.
Joel worries that excessive TDD (say, going from 90% to 100% test coverage) cuts time from other activities that could benefit the software product, such as better usability or additional features users are clamoring for.
Unit tests are absolutely useful as a form of "eating your own dogfood", and documenting the behavior of your system. Even if you disregard the actual results of the tests completely, they're still valuable as documentation and giving you a fresh outside perspective on your codebase.
Joel notes the difficulty of testing the UI (web or executable) versus testing the code behind the UI. The classic method of doing this is probably documented in The Art of UNIX Programming, where you start with a command-line app that takes in and spits out text. The GUI is simply a layer you paste on top of the command-line app, which leads to perfect testability -- but perhaps not such great apps, in the long run. Which is more important?
The hidden context of wondering whether a large switch statement you've written is the right choice is that you've already won -- the types of developers who are actively thinking about their work aren't really the problem.
Our favorite Stack Overflow questions this week are:
- Everyone: Large Switch statements: Bad OOP? The idea that giant switch statements are fundamentally evil is a bit of a knee-jerk reaction. It really depends how simple and straightforward you can make the switch statement.
We answered one listener question on this podcast:
Andrew Davis: "My rule of thumb is that unit tests should be written for clearly defined code that has highly constrained input going in and coming out. Is it even worth writing tests for GUI code?"
Tim Kington: "True test-driven development has one benefit you didn't talk about: you can approach your code from the perspective of the client."
If you'd like to submit a question to be answered in our next episode, record an audio file (90 seconds or less) and mail it to firstname.lastname@example.org. You can record a question using nothing but a telephone and a web browser. We also have a dedicated phone number you can call to leave audio questions at 646-826-3879.
The transcript wiki for this episode is available for public editing.