I was recently discussing code documentation with a junior developer that I am mentoring, and I put forth the four things good documentation should include. After mentioning this to my mentee, they were astounded that no one had put it so succinctly before. So I decided to write down these principles in the event my readers haven’t seen them described this way either.
Good code documentation must tell the next developer (even if it’s the same person) the following four pieces of information:
- Purpose: why the code (be it a library, snippet, method, or class) was written,
- Function: what the code is doing,
- Form: how the code achieves what it’s doing, and
- Usage: how the code is to be used.
For the remainder of this post, I’m going to use the example of a PieChart class that was written to display a pie chart on the screen. It’s a fairly simple concept that completely encapsulates a single piece of functionality that would likely be reused.
Purpose: Why this was code written
Why was this PieChart class created? In our example, it encapsulates all the code necessary to display a pie chart to the user. In our application, we will be displaying a lot of pie charts, so it is best if we have a well written class to handle them. Thus the simple purpose of this class is to make displaying pie charts easier to code.
Generally speaking, this is the easiest of the documentation to write. For one thing, it’s purely opinion. The class was written because you wanted or needed to write it. You just need to convey to the next developer it’s purpose. In doing so, you let the next person to see it understand why it’s an important piece of the overall project or library you created, and they will better grasp how to use it in their code. Furthermore, this part of the documentation does not necessarily need to be verbose. It only needs enough information to inform the developer what it’s all about.
In this part of the documentation you should also list all the assumptions that went in to the making of this code. Here you might want to list alternatives to this code that might have worked if not for the specific requirements you had.
PURPOSE:
PieChart encapsulates the functionality of displaying pie charts
to the user into a reusable class.
Function: What this code is doing
This is a high-level description of the code that you wrote. In our PieChart class example, the code is taking user data and displaying it as a pie chart. That description however, is a little too succinct, and really just a duplicate of the knowledge we gained from the Purpose section.
What we need to do is explain what all the parts of PieChart are doing. This could be broken up in to sections and explained while providing the documentation for Form. For complex code, though, it’s best to have a summary of the functionality separate from the explanation of the mechanics of the code.
FUNCTION: PieChart takes user data and converts it into a displayable format that is then presented to the user. The pie charts are created using the local graphics library, and described using the provided strings. Pie charts can be created to be any size within the screen bounds, and can be placed anywhere on the screen, so long as they are completely within the bounds of the screen. Pie Charts will be created using a set of colors computed to provided contrast between sections. Colors may be supplied if desired.
Form: How this code works
Now we need to get into the details of the code. This is where we explain all the subtle tricks that were used, all the complex algorithms employed, and any assumptions the code makes. Not every method or property needs to be individually documented, especially if they are descriptively named and simple to follow. However, complex methods and method parameters absolutely should be, especially if the comments can be seen with autocomplete editors.
The documentation here should be of the level that if anyone else were to look at (or if you were to come back to it six months from now) there would be no questions as to how it worked. This is where verbosity is appreciated.
Here you need to also explain why one algorithm was chosen over another, especially if the algorithm you are using is non-standard. There are many standard practices for most types of software, and if your code is going to deviate from that, please give adequate documentation as to why and how. I know how much we as developers love to utilize clever tricks in our code; however, if you don’t document that cleverness sufficiently, no one is going to understand or trust what you did.
The following is an example (abbreviated here for space) of a good comment for one method of PieChart, DrawChart().
FORM: /* This method, DrawChart() contains all the graphics code for the drawing of the chart on the screen. It expects to know the size (radius), center location, data array, color array, and description array from the class properties. Without those, this method will fail. Draw loop: calculate arc from data, draw line from center to arc start, draw arc, draw line from arc end to center, fill with color, create description string view, rotate view based upon arc, draw string view. This method will throw an error upon failure. */ func DrawChart()
Usage: How to use this code
Finally, we need to describe how to use the code. For some code this is optional, but only if the usage is simple, obvious, and easily inferred from the code. This is usually only the case with code like simple methods, or highly description enumerations. Everything else should have a usage, and if possible, put in the comments in a way that autocomplete editors can understand it, and self-documenting libraries can read it.
USAGE: PieChart.init(Array userData[], Array userColors[], Array descriptions[], double radius, point centerPoint) userData is an array of values (doubles) that will be used to calculate the percentage portion of pie chart. userColors is an optional array of colors that matches one for one each value. descriptions is an optional array of strings to display within each wedge that matches one for one each value. radius is the radius of the pie chart. centerPoint is the center of the pie chart as a point structure (double x, double y).
The Fifth Tenet: Fun
Neither writing, nor reading, documentation is usually very fun. It’s informative, if done correctly, but it’s often dry and sometimes hard to get through. I like to sprinkle humor in my comments where I can, and I encourage you to do the same. A harmless, purposeful pun or joke based on the context is often very much appreciated by the reader. Be mindful of policy, though. Some employers frown upon this.
Conclusion
Good documentation is part of being a good developer. It is often under appreciated until it’s needed, and then it is too late. I encourage every developer to get into the habit of documenting their code, if for no other reason than they will be able to understand what they have written themselves. I guarantee you, though, that if you diligently write good documentation, your coworkers and collaborators will love you for it.