The first time I sat down to write a book, things went horribly. I tried to piece together an entire story in my head and write it down, from start to finish, all at once. I kept up the charade for a month or so, then burned myself out and gave up part way through.
The second time, I didn’t plan anything out and wrote an entire story from start to finish in three weeks. It was a complete story, but rambles at parts and loses its ability to make any sort of sense less than a quarter of the way in.
This third time, I carefully planned out components and broke the larger narrative into smaller stories. Each of the smaller components stood on its own and could be written, polished, and rewritten independently. Subsequent stories added to the overall narrative and enhanced the feel of each. It was the first time I felt I’d been successful, and it gave me a great sense of pride to be finished with something worthwhile.
It also gave me a new perspective on modular development in software.
Decoupled Development
The failing of test driven development is that it requires you to have a well-thought-out architecture in mind before you ever begin writing real code. If you’re following a traditional “waterfall” development method, this is fairly straight forward. Unfortunately it also means your entire application must be completely planned out and documented before you can write tests. As such, you risk death by documentation and are better suited for a different paradigm.
Instead, I would encourage you use test informed development. As you build each component, write tests for that component at the same time. Your tests serve as further functional documentation for your new code and, honestly, no one will know the difference if you commit both at the same time.
Fundamentally, though, your application should always be broken up into separate components – each should be capable of functioning somewhat on its own. The independent functionality makes for better, more decoupled unit testing. It also make for easy substitution when a newer component is available. Finally, independent modularization means you can partition out development of the larger project to disparate teams.
Unlike the waterfall method, completion of each independent component can be demonstrated to stakeholders before shipping. Under a waterfall scheme, you often must wait for larger milestones before an incremental demonstration can be made – with this more agile scheme you can demo each component independently.
It powers more iterative improvements on your product, taking you from planning to MVP in no time.
How to build a Minimum Viable Product. Amazing. pic.twitter.com/5qKGzPKJHU
— Ryan Robinson (@TheRyanRobinson) December 27, 2014
Often times, the projects I try to build are too much like that first book – or like the car in the first example above. I have a grand idea, and I build tiny pieces that don’t quite do anything on their own. I end up failing around step 3 and never ship a final product because I never reached a stage at which my product was usable.
The second example fits a more refined and productive development pattern. The wheels built in step 1 might not power a car, but they provide a model essential for building wheels to come – and still help power a minimally useful first release. Iterative improvements beyond add new functionality; again, iteratively adding components that still create a functional intermediate product.
Break development apart and you’re left with components that function on their own, components that can be tested/replaced/refactored independently, and a working product after each addition of a new component. It’s a wonder we don’t run all development this way.