Sometimes I like to start a project by doing a few hours of design and then spend the rest of an iteration building a proof of concept. Oftentimes I can get a tremendous amount of functionality roughed out in a system very quickly and then spend the next several iterations making it supportable and maintainable. I like this approach to building a system if it’s sufficiently small because it carries minimal risk. I can build an end-to-end solution quickly to make sure my approach works and once proven I can go back to handle edge cases.
Formal processes like waterfall carry significant risk because you don’t really know what you have until the end of the project when it’s often too late to change it. Agile projects by their very nature are a far less risky. We are constantly verifying with the customer and building software based upon their priorities and feedback. This helps us stay focused on the most high value things to our customer.
When the Agile Manifesto says that we welcome changing requirements even late in the development process they mean that we don’t just tolerate it, we actually welcome it! Allowing the customer to change their mind is an important part of building a valuable system. Just like us, the customer doesn’t always know up front exactly how a feature should behave. Instead of resisting change through a managed process, agility encourages change because ultimately we build a better product when we don’t resist change.
Developing software is a discovery process. We have to understand a problem at a very high level of detail to write software that embodies the solution. As we build software we learn about the problems we are solving and oftentimes that insight can be just as valuable to our customers as the software we produce.