Nick Malik has a post about documentation as it relates to software development, in which he quotes a post from James McGovern:
“I am of the belief that documentation should explain decisions taken and not taken, Why an approach, architecture or algorithm was selected and what else was considered and rejected. “
Frans Bouma is someone who has talked about this before and I agree with this.
Malik and McGovern continue to talk about the role of the architect and the developer as it relates to this, which I generally disagree with, but that’s a topic for another post.
Various developer-centric blogs have talked about how code itself should be self-documenting. To the extent that this means code should be well-written and generally understandable to a similarly situated developer (i.e., someone of the same skill level and business knowledge), it is hard to disagree with. However, this misses the fact that code cannot self-document the code not written, nor why it wasn’t written that way.
I’ll give one example that sticks out from recent experience. At one of those ‘too big to fail’ financial companies, I was working on a system and was assigned to investigate a potential defect. At first glance, what I saw in the code was something that most decent developers (or in this case, myself) would consider appalling. Above (or below, I forget exactly) the method that was actually executing was another version of the method that was entirely commented out.
Normally, this is just terrible. This is what source control is for. Leaving in commented out code is at best totally confusing. When working on a module/subsystem/whatever, there are times when I will comment out a method that I am making a significant change to, simply because it is easier to reverse the change if it turns out it was a mistake to make the change in the first place, or if I want to reset to a known state efficiently. Yes, you can due this with source control, but, let’s face it, sometimes, it’s just easier to do that. But, once the change is made, the previous method should be eliminated, not just left there.
However, in this instance, the previous developer had a very good reason to leave it in. Above the commented out method, she included a comment that said (paraphrasing):
Due to defect number blah, it was decided by Business Analyst blah that this method should change from Blah A to Blah B. However, I am not convinced that this decision won’t be reversed due to potential future evidence. If you are assigned a defect number related to this method, please refer to defect number blah and the previous BA decision for analysis
Now, surely (“Don’t call me ‘Shirley’”), there are different ways in which the same information could have been conveyed to me, the new developer having been assigned the potential new defect. The method itself could have been eliminated, but the same comment left intact. However, assuming that it would have been easy enough to find the previous method in source control and run a compare (which IIRC was questionable, but leave that aside), given the context of what I was investigating, it was more efficient for me to have the previous code actually there. When working in an environment with dozens of active developers working on parts of the same system, and casting this over years of development, this ‘hacky, ugly’ commented out code allowed me to address the details of the potential new defect very quickly.
Regardless of the details of the example, some key points stick out. As an ideal, you should write self-documenting code (and to give a trivial example of something I’ve seen recently, if your variable is of the type “Account” name it that. Don’t name it “pAcnt” for instance. Unless you are writing real-time trading code, name your variables so that it’s obvious what you are talking about. Same with method names, and class names, etc. in other words, basic stuff…but I digress). But even the best self-documenting code can’t explain the decisions behind why the code was written the way that it was and not some other way.
I fully understand the evil that is the traditional design document. Whenever tasked with creating one of those suckers, I cringe at the thought, especially if I am unfamiliar with the target audience of the document. Probably every experienced developer has been faced with the ‘trauma’ of creating the design document that is supposed to contain the actual code that will be developed. Probably every experienced developer has been faced with the even worse ‘trauma’ of being passed a design document that contains the actual code, which never ever ever is correct, and then is tasked with keeping the design document in sync with the actual code developed. Personally, when faced with this situation, I either ‘forget’ to do that, lie about it, or update it later (I don’t recommend this unless you are confident you can get away with this).
But, to tie this back to the original point (finally), where documentation in software development can be of great use is in documenting the decisions why the design took the path that it did. To give yet another recent example, I was asked why a vital production system prevented user action given situation X. Well, the BRD, written and signed-off on (and let’s hear it for the great process of sign-off) 8 months previously said that’s what the system should do given situation X. It didn’t say why it should do that, just that it did. 8 months later, users are complaining that the system is preventing them from taking action, and no one is totally clear why. In environments where BRDs are required (and when/if/why this should or should not be is the topic of yet another post), they should give that explanation. Because what often happens (as the “commented out” code example illustrates) is that a decision is made, then, because no one remembers the reasons behind the original decision, the decision is changed due to new circumstances, and then it is discovered that the new decision fails to take into account the context of the original decision.
If you can follow that.
So, summation: valuable software development documentation documents the decisions behind design considerations (without including code).
Repeat that 5 times fast.