Implementation Decision Rationales – Program Comprehension in Agile
Most of the daily work of a software developer is maintenance and further development of existing software products. Therefore it is crucial for a developer to understand what has been implemented, and this understanding will most often come from reading the code.
In addition to understanding what has been built the developer needs to understand the "why" of the code design, as there are an abundance of possibilities for implementing something (even in the case of an apparently trivial task).
It is necessary to be able to tie the pure syntactical nature of the source code to its meaning in the application domain. This happens whenever a developer tries to understand the structure and behavior of a piece of code - known in academia since the late 70s as Program Understanding or Program Comprehension.
Relevance of Program Comprehension in Agile
Why should these concepts from the pre-OOP Jurassic era of computing matter in contemporary agile software development approaches?
It is evident that the common agile practice of continuous code refactoring increases the need for Program Comprehension as the code has to be understood again and again. Agile projects favor as much face-to-face communication as possible with fellow developers and with non-developer stakeholders, but almost inevitably there will come a time when the only way to understand what has been built (and how it has been built) is to "consult" the code.
Once again, this leads us to Program Comprehension.
Consequently, it is advisable to have documentation that supports more or less directly the Program Comprehension needs of a developer - in addition to the concept of "the code is the documentation".
The agile value "working software over comprehensive documentation" makes it clear that such documentation has to bring a benefit discernible to the customer - to justify the effort of documenting while working in the spirit of the YAGNI principle. A challenging endeavor as we deal with a matter that is apparently related solely to programming.
Design Decision Rationales as a solution
A possible solution could be an approach to documentation based on Design Decision Rationales, originally known from the discipline of system development. By extracting the essence from its various definitions in literature, you can say that a Design Decision Rationale states the reason behind a decision that was made during the design of a software system, to justify and clarify the thinking behind that decision. A useful rationale can also argue why alternative design options have been rejected.
As was stated above, there are many possible ways to implement a design in code. Applied to software development with that in mind, the notion of an "Implementation Decision Rationale" comes to the fore, so that the decisions which were made regarding the implementation are explained. Obviously, that would be helpful for a developer in respect of Program Comprehension. Looking again at the implications of code refactoring, such a rationale could justify, for example, why an obfuscating part of the code was implemented like that (or why it was not refactored subsequently). There are indeed cases where refactoring is virtually impossible due to the extreme costliness of it. Just think of any ugly performance optimization in the code that can hardly be avoided (unless you are not faced with the development of performance-critical software at all).
Are agile values or principles violated?
So, does such a documentation approach align with agile software development?
Such concepts have been incorporated into agile software development in research papers - with a focus on ligthweight producing of the documentation as well as on a supposed facilitation of decision making in teams through it.
Literature for practitioners also substantiates the value of this approach: Andreas Rüping explicitly addresses the idea in his pattern collection for documenting in Agile with a pattern named - not surprisingly - "Design Rationale". Likewise Robert C. Martin (one of the authors of the Agile Manifesto) addresses it explicitly in his Agile book when reflecting on the agile value "working software over comprehensive documentation".
So should this approach be accepted as an agile practice? If so, the documentation should be based on informally represented Design Decision Rationales in text form. There is no common representation of them, but the recommended approach is a short block of text written in natural language - freely adapted from user stories.
Here is a very brief (and fictitious) example of the implementation of credentials verification in a typical login scenario:
password is passed together with its original set date to determine internal encryption
passwords set after 2008-10-01 have been encrypted in DB with SHA-2, not anymore with MD5
Never neglect customer satisfaction!
When the Program Comprehension of a developer is supported by documentation, a consequential benefit sould be the improved quality of the resulting software product. Without doubt this would be of benefit to the customer.
It is, however, questionable whether that benefit is "direct" enough for the customer. Incorporating Program Comprehension does not directly serve customer satisfaction as expressed through the first agile principle ("Our highest priority is to satisfy the customer through early and continuous delivery of valuable software.").
It is quite likely that the customer won't request such documentation, as programming-related matters are usually not understood by non-developers. This means that the developers have to advocate for the production of this "just enough" Program Comprehension documentation.
Where the customer appreciates the qualities of maintainability and supportability this should not be a problem. Also, the ninth agile principle supports appropriate documentation ("Continuous attention to technical excellence and good design enhances agility.").
But if the customer does not appreciate the value of these qualities, then you have a problem. Bear in mind that the first principle incorporates the expression "our highest priority" (certainly, the highest priority does not mean the only priority). We should have a secondary, more discernible benefit in addition to the primary one (support of Program Comprehension) to justify the effort of documenting.
As quoted here from an article in IEEE Expert, there are further identifiable benefits from the inclusion of Design Decision Rationales:
Managers or users can use them to evaluate the design.
Lawyers can use them to determine if the design is intellectual property.
Nonetheless, we don't have to think that far beyond ordinary software development (lawyers are usually not involved as project stakeholder, aren't they?). Instead, consider the facilitation of a crude change impact analysis conducted by a project manager as a non-developer stakeholder. Such an activity could feasibly be enabled by Design Decision Rationales which are understandable - at least partially - by non-developers.
Suggestion for an implementation
This notion of code documentation with developers as the primary target audience and other stakeholders as a secondary one resembles the common employment of xDoc for generating different variants of an API reference. Actually, xDoc could be an effective approach for implementing Design Decision Rationales as discussed in this article.
Why not simply add one or two doc tags for making them explicit? For example, an @decision tag supplemented by one or more @reason tags.
/** * @decision password is passed together with its original set date to determine internal encryption * @reason passwords set after 2008-10-01 have been encrypted in DB with SHA-2, not anymore with MD5 */
It is a straightforward process to customise an xDoc tool for generating a nicely formatted representation of that code documentation. Stating Design Decision Rationales on a method level (doc comments are more or less supposed to be placed there) warrants a certain non-triviality of them (justifying single If statements would certainly be ridiculous).
With that documentation approach, development will probably take longer initially, but the time saved in not needing to struggle to understand the decisions made over and over will more than compensate for this additional effort.
The suggested implementation by means of an xDoc tool is not only lightweight when practiced but also introducing it is lightweight: You can hardly lose anything as you most likely use xDoc anyway (don’t you?). Particular doc comments can be removed quickly if you choose to get rid of them again.
At the very least you gain some practical documentation wisdom specific to agile software development! So why not trying to document your decisions instead of writing the usual, rather aimless code comments?
About the author
Fabian Kiss is a software developer who loves agile and lean environments. In his daily work he is never tired of convincing a stakeholder of the benefits attained by practicing sustainability throughout the entire development lifecycle.
The idea is viable...
There is a solution, though. You can store information about decisions and rationales behind the code in SVN/Git commit’s comment. This way you can clearly see the connection between the code and the decision/reason behind it, and you can also see a HISTORY of decisions that influenced the code.
Re: The idea is viable...
Regarding your specific example, this information can even easily be put into one or more automated tests. That way, we can also ensure that the information doesn't get accidentally ignored when the code gets changed.
Re: The idea is viable...
So, it should be in the code.
Also, maintainers are lazy to look at ANY documentation; don't even try to create one for them.
What a maintainer will do - and I speak from experience, even if not personal - they get a request, they try to locate the class which is most possibly responsible for the change in question, read the comments at the top of the file, near and inside the affected functions, and do the change.
They won't change comments. They're unlikely to add [meaningful] comments. Sometimes, when the comment no longer applies, they remove them, but some of them are too lazy to do that.
That's their working style. This is what you should prepare your source code for.
If a code never leaves its original development team, and the development team doesn't change rapidly (suddenly only one student remains, with the last two original, but 2nd-generation developers filling their notification period - that's "rapid" change) then commit messages are the way to go.
But if the code is to live for 10+ years, the only place where you could put such is the code itself.
So, the real test of a code's style is when it comes to maintainability.
As for Fabian: don't take the manifesto too seriously. Releasing early spaghetti was never an intention of the original authors, I'm sure.