• 6 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 2/7/22

Write the Documentation for Your Project

In the previous chapter, you saw the advantages of quality documentation for alterable and maintainable code, particularly when working in a team.

In this chapter, we’re going to get into the specifics: how to write documentation for a code project.

Organize Your Files

Bad Practices

When working on personal or professional projects of limited scale, you may be tempted to put all the files at the project's root to save time. But if the project becomes bigger, the lack of structure will pose a real problem for code maintenance.

Imagine the millions of lines of code you need to write the kernel of your favorite Linux distribution, placed in a few files at the root of the hierarchy. It would be a mess and impossible to work with!

Over time, projects expand—external libraries are added, new features are developed and become modules, and dependencies become more diverse, meaning that your code files need to be organized!

How to Organize Your Files

There’s no perfect solution, only conventions used in teams or organizations to help you work more efficiently.

If you’re still skeptical, take a look at the following:

  • The structure of an Android project contains sources, resources, tests, and configuration. The different features are organized in specific modules and are self-documented. Also, the Java source code is isolated from the rest of the resources.

  • The structure of a Symfony project separates the source code, the configuration, the tests, third-party libraries, and public resources, following the MVC pattern. This allows it to separate the data model, the view (interface), and the controller (the logic). 

These are examples of clean implementations that you can use as inspiration. I’d recommend at least the following points:

  • To improve the readability and scalability of your code, keep the different features separate (in different modules or files, for example).

  • Separate the source code from the dependencies you’re using for greater clarity.

  • Place tests in a specific directory for tests

  • Another best practice is to physically separate the different environments (prod, dev., etc.).

Use Comments in Your Code

Use Comments Sparingly

Comments are an effective way of clarifying a particular point (such as a specific technique used in a function), implementing your automatic documentation tool (such as Javadoc), or inserting warnings in your code.

Write Self-Documenting Code

In other words, good code documents itself. When you’re about to add a comment, ask yourself how you could instead improve the code to eliminate the need for comments.

Then, make the improvements to the code, and document it to make it even clearer.

Let’s take this simplified example:

//Check if user's credentials allows him to connect
if ((user.login = request.getParameter("login")) && (user.password = request.getParameter("pass")) && (user.secretNumber = request.getParameter("secretNumber")
]))

Consider replacing it with this code:

if (user.hasCredentials())

 You can then implement the authentication check logic in the method  hasCredentials()   and it will make much more sense!

Add Useful Comments

Even with the best effort, the code isn’t clear in some cases, such as when using regular expressions.

Let’s look at the example of this code snippet, which has to do with international phone numbers:

// format matched: plus sign (”+”) followed by groups of up to 14 digits separated by a space
Pattern internationalTelephoneNumberMatcher = Pattern.compile(^\+(?:[0-9]●?){6,14}[0-9]$

);

The above comment helps with understanding the expected format. Using comments is even more essential with more complicated regular expressions.

Many tools can generate documentation automatically from correctly implemented comments, as you saw with Javadoc.

For example, for a function, it would be helpful to explain the following points in comments:

  • A description of the feature.

  • The parameters to be transmitted with a description of their role.

  • The expected result.

  • The version.

  • The author.

  • Specify if the function is obsolete and provide its replacement.

To illustrate this point, I will add comments to a simple function for connecting to a database.

/**
* Allows connection to a postgreSQL database
*
* @param url string of the endpoint to connect to
* @param user string of the user to be connected with
* @param password string of the user
*
* @return void
* @author Francis
* @version 1.0
*/

public void databaseConnect(String url, String user, String password) {
    try {
      Class.forName('org.postgresql.Driver');
      Connection conn = DriverManager.getConnection(url, user, password);
      System.out.println('Connection effective!');
    }
    catch (Exception e) {
      e.printStackTrace();
    }
}

Finally, sometimes a company might impose comment rules that contain legal aspects, such as copyrights. These types of comments are useful as they ensure the protection of private property. Here’s an example:

// Copyright (C) 2020 by Fake Industries
// Released under the terms of the Creative Commons License

Avoid Unnecessary Comments ❌

Repetitive Comments

Check out an example of a Javadoc comment:

/**
* Function that draws a circle on the screen
*
* @param Circle
* @return void
*/

public void drawCircle(Circle circle) {

   ...
}

Here, you can see that the comment is just repeating the code. There’s no need for it.

Obsolete Comments

As explained earlier in the course, be on the lookout for obsolete comments. Over time, these comments may no longer be correct, may lead to errors, or undermine the readability of your code, making it more difficult to maintain and reducing its quality.

Incomprehensible Comments

Despite all your efforts to make your code clear, if you still need to add in a comment, take the time to make it intelligible.

There’s no bigger waste of time than having to rack your brains to understand what another developer meant. And it’s even worse if you have to go into another code module to look for the meaning of a comment!

Take a look at the following code:

public void loadAndWriteJsonFile(String url){
  try
  {
      FileInputStream jsonFile = new FileInputStream(url);
      String jsonString = IOUtils.toString(jsonFile, UTF-8);
      JSONObject jsonObj = new JSONObject(jsonString);
      sendRequest(jsonObj.getString(trademark),jsonObj.getString(owner));
  }
  catch(IOException e)
  {
    // No JSON files means default settings are loaded.
  }
}

The comment inserted here is not very clear—you don’t know which function should load the default settings or if the author simply left this comment here to come back to it later.

It would have been better to write a function that loads default settings rather than leaving a comment. Consider the following correction:

public void loadAndWriteJsonFile(String url){
  try
  {
    FileInputStream jsonFile = new FileInputStream(url);
    String jsonString = IOUtils.toString(jsonFile, UTF-8);
    JSONObject jsonObj = new JSONObject(jsonString);
    sendRequest(jsonObj.getString(trademark),jsonObj.getString(owner));
  }
  catch(IOException e)
  {
    loadDefaultSettings();
  }
} 
Comments for Tracking Changes

Another type of unnecessary comment is on changes made to the code—the changelog.

If you’re working on older code, you might come across these comments, which were often used when versioning tools such as GitHub and SVN weren’t as widely used as they are now. Nowadays, they’re no longer necessary.

For example, a few years ago, it was quite common to see comments like this at the start of a file:

/** Change log (from 17/02/2020)
* --------------------------
* 17/02/2020 : Add constructor to the class ;
* 15/02/2020 : Added the DAO class to the package ;
* 13/02/2020 : Change AddProduct() to AddProductToShappingCart() ;
* 13/02/2020 : Fixed bugs in addProduct() ;
*/

You no longer need to use this type of comment—that’s Git’s job!

Comments for the End of Loops

Finally, it’s best to avoid using comments to signal the end of your control structures, like in the classic bubble sort code below.

public static void triBulle(int tab[])
        {
        int lengthTab = tab.length;
        boolean inversion;
        
        do
            {
            invert = false;

            for(int i=0;i<lengthTab - 1; i++)
                {
                if(tab[i]>tab[i+1])
                    {
                    swap(tab,i,i+1);
                    invert=true;
                    }//end if
                }//end for
            lengthTab--;
            }//end do
        while(invert);
        } //end of function

Except in the case of particularly complex functions, this type of orphan comment needlessly clutters code and makes it unreadable. Instead, try to reduce the complexity of your functions and improve readability using the best practices you saw in the second chapter.

These examples are not exhaustive—this chapter aimed to give you an idea of useful comments and those that aren’t worth including in your code.

Let’s Recap!

  • Streamlining the organization of a code project’s files improves readability and scalability. Separating the different environments and tests are best practices that most modern frameworks allow you to implement. 

  • Good code serves as its own documentation. Ask yourself how to improve it to eliminate the need to add comments. 

In this chapter, you saw how to write code documentation. 

In the next chapter, we will focus on how to publish your documentation online and the best ways of writing your commits. 

Example of certificate of achievement
Example of certificate of achievement