Thursday, March 3, 2011

10 Myths about Writing Design Spec/Doc

In my last post we explored how Code is Design and How Design Spec is Muda (waste).
Idea I'm presenting is simple: Code itself is design.  Writing traditional software design docs describing details like API/class level design is just  a sheer wastage of time and money and is plain irresponsible. (And plain immoral to keep writing them knowing that it is not useful at all).
Again  I'm reiterating the simple mantra : code itself is design.
  • We have sufficiently high level object oriented and functional programming languages.At the same time our libraries are getting smarter and richer. Templated data structures and algorithms add set of powerful tools.
  • It takes more time to write a design document than to write some code that actually embodies and expresses that design.    
  • We need to keep improving the code and keep refactoring. Experimentation is reality. 
  • Everyone who deals with code must understand code so make code understandable and comment it well.
  • Among the many advantages of co-locating extra explanatory description with code itself is that it is always in sync with code, versions are tracked with code. 

Correct Alternative to Writing Design Documents

Here is a simple alternative - it is simplicity in itself and magically effective at the same time. 
  1. Write actual classes and methods stubs in code and write header comments for them. Don't worry about logic yet - just simple return statement returning in method body is good enough. However, if your language supports it then add pre and post conditions (i.e requires/ensures) or the equivalent asserts in the empty method body. 
  2. Build them. Make sure you have document generation enabled. With modern tools like ndoc or javadoc all the information about parameters and classes is then generated automatically. 
  3. Now check in the new code (may be in a dev branch). Now ask other developers/testers to take a look at the generated documentation, better yet ask them to look at your code. Ask them to use the class.

One thing to always keep in mind is that at this point our code is not production ready, bug free or complete - or anything like that.It half baked , unhardened and fluid. And certainly not set in stone. It is in a flux. You can change or refactor your design.  But it is compilable without errors and commented very well.

Debunking the Design Myths
MYTH 1 : Design specs/docs/models must be written for class or API design.
What is better than actually having a compilable stubs for classes and methods? It has all the same information that design spec, possibly even more .
  • If people asking for API design docs can't understand actual method signatures with parameter details then they should shouldn't be asking the design doc in the first place.
  • Stub methods are super useful because they can be built and then actually used in other code. People can actually try out your design. Unlike the design doc your code is executable. 
  • Intellisense works with your "design"
  • Tools can tell you if your comments are missing or not in line with actual method parameters.   
Don't write word docs. Write actual class and method stubs. There is nothing better than executable design i.e code. It takes more time to write a design document than to write some code that actually embodies and expresses that design.

MYTH 2:  Design spec helps with early feedback.   
Wrong! You won't generally know if your design is right until you have used it. (Otherwise why ask for the feedback in the first place.)
So to repeat my mantra: Don't write docs write stubs for classes
Once you have checked in the stubs and ask others to use it in their code. There is nothing better than trying out your code with couple of samples. Ask others to try out you code and ask for the feedback on completeness, ask how it feels to use you design.
Last but not least, write samples yourself and share them.

  • Now or later ultimately other must use your classes/methods. So why not use the stubs right now to see if design can be improved. 
  • Others will often make suggestions based on concrete things like "Can you return an List<Foo> instead of Foo[]? because it's hassle converting and casting all the time". 
  • Test team and you yourself can start writing the unit tests and acceptance tests, which further clarifies the design and actually helps you understand the intricacies. 
  • If you add preconditions, post-conditions and invariants then that is yet another way to comprehend the design. You can even force compiler + static analyzer to give you some feedback.
  • You can run the automated tools like FxCop and others to see it you are confirming to the design patterns.
None of this is actually possible with design document.

MYTH 3: Design spec explains how code works.
Absolute bullshit! 
  • Comment your code well and people will comprehend your code. There is nothing better than actually reading the code to understand code.
  • Choose descriptive names and make an effort to write very clean code. When you make a hack. Put comment. 
  • If you are using design patterns then choose names to reflect that. Let the code speak for itself. 
  • In class description write bullet point description of responsibilities and collaborations. 
Here is  simple trick that can solve most of your documentation problems as well as coding problems. Write some pseudo code in the method body first. Now for each step in the pseudo code write the actual code leaving the original pseudo code in comments. 
Good developers should be able to read the well-written and well-commented code and mentally walk through it. So spend time writing clean beautiful code rather than pretty word documents.

MYTH 4: Design doc needs to be written before the code.
One of the purpose of the design doc is to make sure that maintainers understand how code works. Instead of worrying about the design doc before writing new code. Take some time to comment and clean the code after you are done writing code. That will bring more rewards that writing stupid design doc that gets lost. 
  • If you write public APIs then obviously you can write 'higher quality' documentation after you have fixed all the bugs. For that matter it doesn't make sense to release a design document before the product itself. So ideally write design document after your code is written, tested and ready to ship. It has better chance of reflecting how code actually works.
  • If general population is not going to see design documentation then don't waste time writing one. We already know that combination of code stub and a few tests is far better than API design doc in getting feedback. 
MYTH 5: When you have external dependency or you are someone else's dependency you need a design spec.
Create two assemblies one for defining interface and other for implementation. Code the interface assembly first.Write some sample usage code. Give them interface assembly and samples, get feedback on it.

MYTH 6:  Test team needs design spec. 
They don't. They need list of scenarios to test and actual classes/method that they need to test. It is better to give them compilable stubs so they can start writing tests. Now you can actually use them TDD fashion!  All the testing team needs to do is to understand what code is supposed to do and actually reading the code to search for bugs. Don't waste time reading and writing design specs.  To repeat what has already been said before: design by contract, asserts and unit tests can only be added and tested against the real compilable code not against the doc. In addition, writing acceptance tests can actually be used to drive design.

MYTH 7:  Big software needs big teams and therefore detailed design specs.
If you are writing monoliths you have a bigger problem than simple design specs. 
Ideally your software is modular and component based, which means small teams can independently build components as long as interfaces are well-defined. 
This means 

  • Strict separation between interface and implementationConsumers of your interface should not be forced to know internal details of your design. 
  • Define assembly containing interface, again don't write design docs write the interface code and generate help files from the inline comments. 
  • Share the interface code with others. All the things we talked about writing code instead of docs still remains true. 

MYTH 8: The is extra information that can not be explained in code.
This is actually not true. Most of the information falls into one of these groups

  • Structured information closely tied to the code. This can often be integrated using custom tags. Eg. Class-Resposibility-Collaboration can be expressed using <responsibility> <collaboration> tags. Similarly for the things like algorithmic complexity.
  • Higher order design information like grammar, patterns and state machines which is often expressed at higher level for tools like yacc/lex/bison , make etc.  All these are just 'code' so you can always comment it.
  • Details about why particular data structure was used or why particular algorithm was chosen. I think you can always add this kind of extra information at the appropriate comments at the right place. 
  • Database design results in bunch of tables and queries which again is better expressed with well commented SQL code.
  • Modern UI design is based on declarative languages, once again can be just well commented code.
MYTH 9: Design document can be shared,tracked better through collaboration tools.
You seriously believe tracking commented code through SVN, perforce etc is somehow inferior to tracking it through any other way? People can still use the collaboration tools to review the code changes.  

MYTH 10: There are others who don't deal with the code itself but still need design spec.
No there is no one like that generally. Check your assumptions. Either they are blindly following the ritual or they need some completely different piece of information that design document could not possibly have provided in the first place.
People who don't read, write or consume code on everyday basis do not need to know about any internal details about it's design. What people need is an one page overview document can be written after code is written,tested and ready to be shipped.

Conclusion : Code is Design. Start writing code instead of design documents.

No comments:

Post a Comment