Formatting

Code formatting is important.

Vertical Openness Between Concepts

Each blank line is a visual cue that identifies a new and separate concept.

There are blank lines that separate the package declaration, the import(s), and each of the functions.

package com.gpcoder;

import java.io.BufferedReader;

public class Example {

    public static final String FILE_NAME = "user.csv";
    public static final String CSV_SEPARATOR = ",";

    public void method1() {
    }

    public void method2() {
    }

}

Lines of code that are tightly related should appear vertically dense.

The useless comments break the close association of the two instance variables.

/**
    * The class name of the reporter listener
    */
   private String className;
   
   /**
    * The properties of the reporter listener
    */
   private List<Property> properties = new ArrayList<>();

   public void addProperty(Property property) {
       properties.add(property);
   }
private String className;
private List<Property> properties = new ArrayList<>();

public void addProperty(Property property) {
    properties.add(property);
}

Place dependent functions vertically close

If one function calls another, they should be vertically close, and the caller should be above the callee.

public void createUser(UserDto userDto) {
    validateUser(userDto);
    userRepository.saveUser(userDto);
    sendEmailNotification(userDto);
}

public void deleteUser(Long userId) {
    if (isUserInUse(userId)) {
        throw new UserInUseException();
    }
    userRepository.deleteUserById(userId);
}

private void sendEmailNotification(UserDto userDto) {
}

private boolean isUserInUse(Long userId) {
}

private void validateUser(UserDto userDto) {
}

public void createUser(UserDto userDto) {
    validateUser(userDto);
    userRepository.saveUser(userDto);
    sendEmailNotification(userDto);
}

private void validateUser(UserDto userDto) {
}

private void sendEmailNotification(UserDto userDto) {
}

public void deleteUser(Long userId) {
    if (isUserInUse(userId)) {
        throw new UserInUseException();
    }
    userRepository.deleteUserById(userId);
}

private boolean isUserInUse(Long userId) {
}

Declare variables vertically close to their usage

public UserStatisticResponse userStatistics(List<User> users) {
    UserStatisticResponse response = new UserStatisticResponse();
    List<User> admins = new ArrayList<>(); 
    List<User> guests = new ArrayList<>();
    for (User user : users) {
        if (isAdmin(user)) {
            admins.add(user);
        } else {
            guests.add(user);
        }
    }
    response.setAdmins(admins);
    response.setGuests(guests);
    return response;
}
public UserStatisticResponse userStatistics(List<User> users) {
    List<User> admins = new ArrayList<>();
    List<User> guests = new ArrayList<>();
    
    for (User user : users) {
        if (isAdmin(user)) {
            admins.add(user);
        } else {
            guests.add(user);
        }
    }

    UserStatisticResponse response = new UserStatisticResponse();
    response.setAdmins(admins);
    response.setGuests(guests);
    return response;
}

Use horizontal separation and density so that code reads nicely

We use horizontal white space to associate things that are strongly related and disassociate things that are more weakly related.

private void measureLine(String line) { // 1
    lineCount++;
    int lineSize = line.length(); // 2
    totalChars += lineSize;
    lineWidthHistogram.addLine(lineSize, lineCount); // 3
    recordWidestLine(lineSize);
}
  • (1) I didn’t put spaces between the function names and the opening parenthesis. This is because the function and its arguments are closely related. Separating them makes them appear disjoined instead of conjoined.

  • (2) I surrounded the assignment operators with white space to accentuate them. Assignment statements have two distinct and major elements: the left side and the right side

  • (3) I separate arguments within the function call parenthesis to accentuate the comma and show that the arguments are separate.

Horizontal Alignment

public class FitNesseExpediter implements ResponseSender {
     private   Socket           socket;
     private   InputStream      input;
     private   OutputStream     output;
     private   Request          request;
     private   Response         response;
}
public class FitNesseExpediter implements ResponseSender {
    private Socket socket;
    private InputStream input;
    private OutputStream output;
    private Request request;
    private Response response;
}

Breaking Indentation

public class CommentWidget extends TextWidget {

     public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";

     public CommentWidget(ParentWidget parent, String text){super(parent, text);}

     public String render() throws Exception {return ""; }

}
public class CommentWidget extends TextWidget {

    public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";

    public CommentWidget(ParentWidget parent, String text) {
        super(parent, text);
    }

    public String render() throws Exception {
        return "";
    }
}

Team Rules

Every programmer has his/her own favorite formatting rules, but if he/she works in a team, then the team rules.

A team of developers should agree upon a single formatting style, and then every member of that team should use that style. We want the software to have a consistent style. We don’t want it to appear to have been written by a bunch of disagreeing individuals.

The rules we should follow are coding standards documents:

Many IDEs support coding style checking, the team can define the coding style template and share it to all team members. Refer to Checkstyle development tool.

Last updated