Preface
Several years ago, when I was a full-time C# developer working for a .NET consultancy in the United Kingdom, I embarked on a goal to improve the quality of software I developed. I was fed up with writing software and having the customer find bugs that I felt I should have caught, and disappointed that I didn’t know how to use OO programming to model real-world problems. So I learned about SOLID, became a TDD fanatic, and read up on things like dependency injection and design patterns. And my software did improve! My clients were happier, and my managers were pleased with the lower bug rates.
But soon afterward, I once again became frustrated with a lack of progress. Did we really need this amount of rigor, of process, and of unit tests in order to become proficient software developers? I knew that I’d taken a step forward in terms of quality by adopting SOLID and TDD, but I wanted to achieve it in a more productive fashion. I wanted more support from my programming language to do the right thing by default; something that guided me to the “pit of success” without my needing to use a myriad of design patterns in a specific way, and allowed me to get to the heart of a problem that I was trying to solve.