There are many fans of Object-Oriented principles like loose coupling, design patterns, and principles like
SOLID and
DRY. Unfortunately, there are as many or more who are aware of these principles but believe they are not of pragmatic value, but instead are only 'theoretical' or 'academic'. Because principles like these have become part of the Object-Oriented canon and are taught in programming courses, people lose sight of the fact that these principles did not develop in a laboratory or classroom as a result of some theoretical work, but instead are hard-won and field-tested principles developed in the trenches of software development, to solve real-world problems encountered over the years.
In this tutorial, I hope to give a flavor of just a few of the vast number of ways that adherence to these principles can help us build quality software that better helps us meet business needs, and is a very pragmatic way to develop software. I also hope to show the link between building quality software that adheres to these principles, and building more testable software.
Let's pretend we're ACME, a company in the Doing It All business. To help us with our job, we've developed a Wizbang Widget. If you drop this widget in a project and call its 'DoItAll()' method, it will
- Log things to the company's standard Logger
- Announce certain events to the company's standard Event Listener
- Go to the company's standard Repository to get a Thing with the provided ID
- Pass that thing to another component developed by ACME, CoolComponent. CoolComponent will tell us what noise a Thing makes when Poked With A Pointed Stick.
- Determine if the Thing conforms to industry rules. This is the big deal, the 'secret sauce' of the Wizbang Widget. The company has spent many years and hundreds of thousands - arguably millions - of dollars perfecting this algorithm.
- Call over to the company's web service, passing it the Thing (serialized) and the noise it made when Poked With A Pointed Stick. The web service will record these things in a company database.
Now pretend we've been asked to develop a Unit Test suite around Wizbang Widget. What we're going to look at now are the problems posed to Unit Testing because of the design of Wizbang Widget. At the same time we'll look at some of the ways that Wizbang Widget's design violates design principles like SOLID principles. As we progress through this set of exercises, we'll introduce other goals for the Wizbang Widget, and we'll see how designing/refactoring for testability also promotes generally good design (aka a
Deep Synergy Between Testability And Good Design), and why generally good design principles pragmatically matter.