Design Before Writing Code
I always believe requirement analysis and implementation design are two important steps that should not be ignored. No matter how small the team is, no matter how short your release period is, and no matter how much cost you can only afford.
I find requirement analysis is hard to be ignored, although many teams may not do well on this. That’s probably because that the core of software development is to “translate” the real world objects and behaviors into models and logics that computer can understand. And since there are always gaps between these two worlds, communication has be be conducted between people in the two worlds. The result of such communication becomes the major part of the requirement analysis.
However, I notice that the implementation design is often ignored. An inadequate analogy could be how a compiler works. After compiler “understands” your requirements by reading your code, it could directly translate it into machine code (the implementation), without the intermediate layer (assembly code or bytecode). We ignore the design phase because it feels unnecessary. We like it to be done while typing the code so that we can see the results ASAP.
In my experience, I never see any good outcome when developers jump into the code immediately. I do see this happens a lot though in startup companies, because they usually lack of resources and time, and they want to ship fast to maintain competitiveness. Often times, people try to make an excuse by saying that it’s only proof of concept. Be skeptical about that, because those POC code usually ends up running in production!
I think the drawbacks of starting the coding stage without implementation design are:
-
it slows down the development. Things may not well thought out, and you may find unexpected blockers during the middle of development.
-
it damages the team collaboration and trust. Without design, you may find the work is hard to break into sub tasks, and one of the worst results is that one team member (the “leader”) may end up taking most of the work, while others know little about the details. In the long run, it creates a codebase that’s hard to maintain, and leave with few people that dare to touch the code.
-
the code will end up not well organized. It will make the code hard to understand by others, and hard to maintain in the future.
-
the code will lack of test coverage and thus bring more bugs. The developer will very likely misunderstand part of the requirements or fail to consider all the possible scenarios of the requirements.
-
it slows down the code review. The code review is now including design review, and the reviewer has to understand the design by reading the code. This whole process will end up taking much longer time, and a lot of debates will end up around the design. What’s worse is that, because a lot of things have already been coded, it’s really hard for the reviewer to say: “I don’t really like the design at all” at this point, and the result is usually compromises which will likely end up as tech debt in the future.
Trying to get to the code done as quickly as possible brings only the illusion of efficiency. The new code will be built on top of smell code, which then brings teach debts that will cause more time and effort to fix in a longer term.
How to make requirement analysis and implementation design efficient and less cumbersome, and how to adapt them into the Agile development principles can be other interesting topics, but no matter what, we should not ignore the analysis and design phases.