Formatting
Code formatting is important.
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);
}
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) {
}
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;
}
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.
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;
}
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 "";
}
}
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.