By now you’ve probably figured out that I am a weirdo and that I like doing things differently than other people. In fact, I am an advocate of doing things backward.
But I’m not being random here. As it turns out, the way most people build software includes some of the worst inefficiencies that I can imagine, so doing almost anything differently can be an improvement. In traditional software, we put testing off to the very end of a project but I say let’s write our test first so we can set our expectations on what we want to build.
Conversely, most of the time people think about doing their design upfront before they actually build their system. Well, I’m not advocating that we do all of our design at the end of development, but I find that there are many aspects of design that we can put off until later and when we do it gives us the flexibility to make better decisions towards the end of development.
The fourth principle in Lean Software Development, which is an Agile software development methodology, says to “Defer important decisions until the last responsible moment.”
This is because will know more about the problem we’re solving later. We will be smarter and more informed later so if we can, it’s better to wait before making important decisions. This forces us to think about creating an optimal sequence for the decisions we need to make. In my experience, understanding this can make massive improvements in productivity… and few people do it.
Practice 8, Implement the Design Last, is also based upon a set of techniques that I have been finding valuable for building out behaviors in a system. Rather than doing my design upfront, I may acknowledge that there is a pattern in my requirements but I don’t go there initially. Instead, I write a simple implementation to make my behavioral tests pass. This gets me good tests that are in the green, which means that I can refactor safely.
It’s in the refactor step that I start injecting patterns and good design into my systems. I find that taking this approach is highly efficient and effective. Essentially I am emerging a system or a feature or a behavior incrementally. I find this a highly effective and efficient way of building software and so has the thousands of developers I shared these techniques with.
The following seven blog posts are based on a section in my book, Beyond Legacy Code: Nine Practices to Extend the Life (and Value) of Your Software, called Seven Strategies for Doing Emergent Design.
Emergent design is not sloppy design or irresponsible development. It’s a shame when people who don’t understand it give it that label but it’s also understandable when newbies try to apply this very advanced practice.
I believe that emergent design is one of the most disciplined and advanced practices in software development and I consistently have seen it produce high-quality results, but only once you understand a great deal. There is a reason that it is an advanced practice. It requires experience and a diverse skillset. You need to have good design skills, understand object-oriented programming and design patterns, understand good principles and practices, plus a host of other things.
Just starting a project saying that you’ll do emergent design and then not follow good software development principles and practices—not looking to discover and recognize design patterns—isn’t doing emergent design. Emergent design requires a strong adherence to code quality where software is constantly refactored and kept clean.
In these next seven blog posts, I will attempt to briefly describe seven key skills for effectively doing emergent design. These skills are easy to name but can take a lifetime to master.
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: « Use Accurate Examples
Next Post: Understand Object-Oriented Design »