How many times we realize that the software was implemented in the way very different from the original design? It is an overused example to describe the problem we are facing every day. That’s the reason I will not call design doc review until I have implemented certain amount of the prototyping code and have the confidence about the design accuracy. Software engineers hate to write design document, and it will change during implementation anyway. And sometimes, the design docs are more about recapping what we have done rather than the implementation guideline. I do not think it is because the software engineers are incapable to design accurately, but why?
Let’s give a real life example, say you are planning the trip to the following address:
One Microsoft Way
Redmond, WA 98052
I am pretty sure you will do a good and accurate trip plan by using tools like http://local.live.com. But, what if I give you the following address (my home address in China)?
Bi Tao Bei Yuan
Zhong Shan District,
Dalian, Liaoning 116001
Even you might have excellent route plan, you will not very confident about issues like, foreign language, travel insurance, car rental, hotel, food, medical emergency etc. It is exactly the same problem we are facing in software design - many issues beside original requirements are vital and hidden. Most of projects we are working on today are like trips to foreign countries, which we have never been to. There are uncertainties along the way and some unknown issues will not pop up until you actually get there, which could impact your design dramatically. How to deal with those hidden issues and make your design more accurate? There are couples of lessons I have learned over years and want to share them with you. You are welcomed to add more.
First of all, identify the scope. Believe or not, many projects do not have a clear scope until they are called code completed. Put in another way, the scope of software are sort of determined by development timeline. It is not anybody’s fault. It is merely one of the characteristics of software development – unpredictability. I am not saying that we should precisely define the scope before design, which is not practical at all. However, I strongly believe we should have clearly defined and prioritized items in a pipeline, which might or might not go into scope. By having the big picture in mind, we can avoid changing software design dramatically whenever we adjust the project scope.
Secondly, identify the problematic items within the scope. Those items are unfamiliar to us and will cause uncertainties. We do not want to get into a situation that, when the project is 80% complete and find out that a critical component is technically not feasible. Here is an example of uncertainty from non-functional requirements. Say, we design online gaming software over some platform, later we realized that the platform cannot provide the real-time message delivery channel required by your gaming system. What a “surprise” if we have completed most of our code on top of that platform?
Third, mitigate the uncertainties (also the risks) by prototypes. This is the skill I learned back in CMU. Uncertainties or hidden issues in software development can cause dramatic architecture impact or fail your project right away. To ensure we are heading the right direction with correct assumption, we need to do some experiments. They can be very small and even throw-away projects, however they should cover the real concerns we have in mind.
Software design it is very complicated tasks. There are tons of books talking about it. They start from different perspectives, all come to one common goal – make software development more predictable.