Skip to content

Coding Standard#

Java#

Clean code#

  • Clean code is code that other developers can easily read, understand, and add to.
  • Developers can easily understand what the code is doing without going into low-level implementation details. Good code is self-documented.
  • Clean code is easy to maintain in the long run, easy to update and extend.
  • KISS - Keep it stupid simple.
  • Single responsibility - a class/function should do only one thing.
  • DRY - Don't repeat yourself.

Names#

  • The name of a variable, function, or class should tell why it exists, what it does, and how it is used.
  • classes and objects should have noun or noun phrase names → Example: Vehicle, Invoice, ConfigurationPage etc...
  • methods should have verb or verb phrase names → Example: deleteInvoice, createVehicle, etc...
  • methods names for principal operations should start with: get, create, update, delete.
  • choosing names that reveal the intent make it much easier to understand the code and to work on it.
  • Don't mislead by using inappropriate naming

    • Avoid using words that can lead other developers to confusion, such as the word List.

      1
      private List<Student> students;
      
      1
      private List<Student> studentList;
      
    • Avoid including the type of a variable in the variable name.

      1
      private Integer amount;
      
      1
      private Integer amountInteger;
      
    • Don't use long variable/method or class names that are very similar to one another.

      1
      2
      3
      4
      5
      6
      7
      public class JwtHandler {
      
          public boolean IsValidated(String jwtToken) {
              ... 
          }
      
      }
      
      1
      2
      3
      4
      5
      6
      7
      public class PasswordJsonWebTokenValidator {
      
          public boolean IsJsonWebTokenPasswordValid(String jwtToken) {
              ... 
          }
      
      }
      
    • Avoid uppercase o (O) and lowercase l (L) in variable names.

    • Use names that can be pronounced.
    • Use names that can be searched.
    • Don't use single characters in class, method, and variable names (example: a, e, b, c etc...). Not only they do not reveal their intention, but when searching for the usage of variable e you will get irreverent results.

Modules#

  • A new component should be composed of two parts: api and impl.
  • api module contains interfaces, dto classes, and exceptions which will be used on impl module.
  • Impl module will contain the logic of the new component and the Junit tests.
  • Each package should reveal the reason:
  • application - service classes
  • domain - api → dto classes, impl→ dao classes
  • exception - exception classes
  • config - configuration classes
  • infrastructure - lower-level classes that deal with systems directly: service classes, repository, etc.
  • rest - controller classes

Classes#

  • Should be small.
  • Should have one and only one reason.

Function#

  • Should be small and easy to be understood. Up to 20 lines long, preferably smaller.
  • Do one thing.
  • Blocks inside if, else, while statements should be function calls, keeping the size down and also contributing to code documentation by using descriptive names.
  • Avoid nested if statements. Function block-level indentation should only go up to two levels deep.

Argument#

  • The rule for the number of arguments a function should have simple, less as possible
  • Three arguments should be avoided where possible and more than three requires special justification and should be avoided at all costs.

Flag Arguments#

  • Passing a boolean into a function is bad practice.
  • It gives the idea that the function does two things if the boolean is false and another if it is true.

Argument objects#

  • When a function requires more than three arguments you should consider grouping them into separate classes.

Argument lists#

  • Argument lists of the same type, used for example in String.format are considered a single argument since it can be treated as a List.

Verbs and keywords:#

  • Function naming should not be dealt with superficially. In the case of a monadic function, for example, the name should form a verb -> noun pair.
  • For example: save(user).

Avoid side effects#

  • If your function is called save(user), as in the example above, it should only do this one thing, save the user input data.

Error Handling#

  • Use exceptions rather than return codes.
  • Don't return null.
  • Define custom exceptions.

Comments#

  • We should avoid using comments because that reveals that the code is not written well comments should be used only when our code cannot express in an easy-to-understand manner what it is doing log comments should be used only where is absolutely necessary.
  • A few reasons why comments should be avoided:
    • Comments clutter code.
    • Comments can encourage bad code.
    • Comments can "lie". Code evolves constantly and comments can be outdated and not reflect what the code is actually doing.
    • Time invested in writing comments should be directed in writing better code that is easy to understand.

Warning#

  • Some comments can be useful to prevent other developers from making changes that would have unwanted consequences. The below comment, for example, could prevent another programmer from using a static initializer.

TODOs#

  • TODO comments can be used as:
    • Reminders to complete functionality that cannot be completed during the time of writing (for whatever reason).
    • Reminders for other developers to look at potential problems.
    • Reminders to look for better naming.
    • Delete deprecated functionality.
  • Whatever the reason for leaving TODOs it is important to regularly check them and eliminate them. TODOs should not be used as excuses to write bad code.

Formatting conventions#

  • The most important aspect of formatting is standardization and consistency. Formatting helps good communication between developers, a reason why it should not be ignored.

Vertical formatting#

  • Here are a few good principles to follow:
    • File names and modules should accurately describe it's high-level purpose.
    • At the beginning of a file, we should find high-level details, concepts, and algorithms.
    • As we read down into the source file we should go from high-level details to lower-level implementation details.
    • Use blank lines only to separate concepts.
    • Keep lines of code that are tightly related in functionality together.
    • Keep imports and dependency declarations clean and updated.
    • Closely related concepts should be kept together.
    • Because of (7) try to avoid using protected variables too often.
    • Variables should be declared as close as possible to their usage.
    • Local variables should appear at the top of the method.
    • Loop variables should be declared inside the loop.
    • Instance variables should be declared at the top of the class.
    • Dependent functions should be vertically close to each other.
    • Function call dependency should be ordered from top to bottom.
    • Order of declaration should be:
      • static variables.
      • public variables.
      • protected variables.
      • no access modifier (package) variables.
      • private variables.
      • constructors.
      • methods.
    • Methods should be grouped by functionality rather than by scope or accessibility. For example, a private class method can be in between two public instance methods. The goal is to make reading and understanding the code easier.

Horizontal formatting#

  • Each line should be as short as possible. It is easier to read and to follow across the code.
  • The rule of thumb is to keep the lines in a file to a length that doesn't force horizontal scrolling. On a typical modern display, this can vary from 80 to 120 characters in normal readable font size.
  • Just as in vertical formatting there are a few principles that each developer should follow:
    • Use horizontal white spaces to associate or disassociate things that are related or not related.
    • Use indentation to accentuate the hierarchy of scopes in a file.
    • Avoid collapsing scopes.
    • Avoid dummy scopes with no body or use visible braces to make them visible.

Checkstyle#

  • For the checkstyle we use SonarLint
    • It can be added from IntelliJ IDEA plugins section.
    • We use the default configuration.

References#