CSC/ECE 517 Fall 2009/wiki3 13 is
Self-Documenting Code
Introduction
One of the characteristics of elegant, well-designed code is that it should be easy for someone to read the code and understand exactly what the code does. It should be possible to understand the code by using the names and comments within the code without needing any additional documentation. Source code that is easy to read and understand is known as self-documenting code.
There are numerous advantages to self-documenting code. One of the biggest advantages is the fact that it is often quite easy to maintain or extend code that is self-documenting. Another advantage is the fact that it is not essential to have external sources of documentation to understand how the code works. Self-documentation can also help prevent certain types of bugs or defects from being introduced in the code due to the fact that developers usually have a clearer understanding of what the code does.
Techniques
By following a few simple techniques and guidelines developers can produce self-documenting code fairly easily.
Whitespace
Appropriate use of blank lines between and indentation can greatly improve the readability of source code. Blank lines should be inserted between logical sections or blocks of code. In most languages code contained within a block should be indented to make it clear that it is part of a block of code. Consider the following examples:
[BAD CODE EXAMPLE] [GOOD CODE EXAMPLE]
Example B is much easier to read because of the proper use of whitespace. It is usually best to avoid putting more than one statement of code on a single line unless the statements are very short and very simple. Long statements can (and should) be broken into multiple lines with indentation to indicate that the additional lines belong to the same statement.
Some languages have style guidelines that describe where and when whitespace should be used, such has which lines of a method should be indented and where block identifiers such as { or } should be located. Links to style guidelines for various languages are included below.
Naming Convention
Choosing good names is critical to writing self-documenting code. In many languages objects, variables, and methods are identified by their name. Good code uses names that are clear and descriptive. Descriptive names do not have to be long or verbose and it is often better to use shorter names with logical abbreviations instead of a really long name. For instance, the variable names “userIdentifcationValue” and “userID” are both fairly descriptive but “userID” is shorter and easier to type and is just as clear as “userIdentifcationValue”. Bad code uses names that are generic or that provide no indication what the item is used for such as i, j, n, num, r, x, or cv. Consider the following examples:
[BAD EXAMPLE] [GOOD EXAMPLE]
It is very difficult to figure out what the first code section does because none of the variables, objects, or methods have descriptive names. The second code section uses descriptive names and is much easier to read and understand.
Many programming languages have established naming conventions that are used to distinguish a variable from an object or a method. It is important for a programmer to follow the established naming convention for the language that he or she is writing in. Links to naming conventions for various languages are included below.
Code Structure and Comments
There are often many different ways of writing code to accomplishing a particular task. Generally a simple approach to a problem produces code that is more readable and easier to understand than a complex solution.
Some complex algorithms can be greatly simplified by moving pieces of code into separate methods or functions. Code that has well defined methods generally exhibits good object oriented design in addition to being easier to understand and maintain. Consider the following examples:
[BAD EXAMPLE] [GOOD EXAMPLE]
The first example has a lot of code to handle the process of drawing lines making it harder to understand what else the code is doing. The second example moves the task of drawing the lines to a separate drawing method which helps simplify the code and make it easier to follow.
Generally the simpler the code is, the easier it is to understand it. When given the choice between a simple implementation and a complex one the simpler implementation will almost always be easier to debug and maintain.
Some coding problems are very difficult to solve in a straightforward, easy to understand manner. In these situations it is important to thoroughly document the code with comments that explain exactly what is being done and how. In some cases it is also a good idea to include comments that describe why the section was implemented the way it is.