2024 Public Training Schedule
December 9 – 12, 2024 – Agile Analysis and Design Patterns – Half-Day Sessions
2025 Public Training Schedule
January 14 – 17, 2025 – Agile Analysis and Design Patterns – Half-Day Sessions
(c) 2024 To Be Agile
One of the reasons that I’m such a proponent of doing emergent design or just-in-time design, is that this is how we learn a system and this is typically how a system needs to be built. It’s fallacious to believe that you can easily envision every aspect of a complex system and come up with a comprehensive set of requirements that don’t need to change. Really smart people can’t do this so the rest of us shouldn’t be expected to do this either.
Imagine what the movies would be like if actors had to get every shot perfect on the first take. We would see far fewer risks being taken and far more mistakes would end up in the final version of movies. Being able to have multiple takes gives an actor and a director the freedom to try different things and often they can come up with better ideas than they originally imagined. The same thing is true in the software profession.
If software developers believe that they have to come up with the right design initially because it can’t be changed later then they have a lot of pressure to get it right. Not only do I find that this is an enormously difficult constraint, but I also find that it is typically an unnecessary one because you don’t have to come up with a design and stick with it evermore in software.
After all, software is soft. This means that we can take advantage of the changeability of code.
The key to doing emergent design successfully is being willing two change your design in the light of new requirements. When we get good at doing this we discover that most of the time, changing a design is a trivial activity that’s both safe and straightforward to do, when we know how to refactor.
When we reach that level of craftsmanship then software development can be a lot more fun because suddenly the pressure is off. We don’t have to come up with the perfect design because we know that we can refactor our code and change the design anytime in the future that it makes sense to do so. When we realize that going from one design to another design is usually a simple matter of repackaging existing functionality and that oftentimes the hard part is getting the functionality to work in the first place, then we can focus our refactoring efforts on finding a more extensible design for code that already works.
As the expression says, hindsight is 20/20. We often know things in retrospect that we wish we knew ahead of time. Refactoring code gives us a second chance. It gives us that opportunity to incorporate what we didn’t know at the start and this can vastly improve the design of our code, as well as the opportunities for extending it in the future.
We often learn in chunks. Even though there is the refactor step when doing test-first development, so we are constantly doing refactoring in the small, we still need to occasionally do refactoring in the large. It’s because we learn in chunks that we have to do refactoring in the large. We want to take our learning and bring it back into our code, and in order to do this when we have new and significant insights often requires taking some extra time and refactoring code so that the design reflects our current thinking.
Note: This blog post is based on one of the “Seven Strategies…” sections in my book, Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software.
Previous Post: « Refactor to Clean Up as You Go
Next Post: Refactor to Clean Up Before Moving On »