Coding best practices – Java 8, Spring and Maven

Null checks – Developers no longer have to write null check conditions while programming, thanks to Java 8 Optional.

If your are writing a method which takes n number of params and they are prone to NullPointerException then use below expressions to avoid NullPointerException. nice and clean

public void addition(Integer a, Integer b) throws InvalidParamException {
// Note: InvalidParamException is custom exception, define your own
Optional.ofNullable(a).orElseThrow(new InvalidParamException("Null value received"));  
Optional.ofNullable(b).orElseThrow(new InvalidParamException("Null value received"));

// TODO: rest of the logic
}

Make a habit of using above expression more which makes your code look clean and readable.

Read handling-nullpointerexception-in-java-8-streams for using above expressions in Java 8 streams.

If you are writing a new method to fill a POJO from another Object then you can use below expressions
public Student transform(Person p){
  Student s = new Student();

  Optional.ofNullable(p.getName()).ifPresent(name -> s.setName(name));
  Optional.ofNullable(p.getAge()).ifPresent(age -> s.setAge(age));
  //... do same all other fields

  return s;
}

Static collections in Spring.

Most of the times we define a static HashMap or ArrayList to keep some data in RAM. for ex. There are N types of students and we need to show them in a drop down when user opens the registration from, in this case we don’t have to fetch student types list ever time from database when user loads the form, which is a performance (or a useless) hit. So to improve the performance a bit we can fetch them once (since it is a static data) when the application starts and keep them in a ArrayList.

In a typical case, to make that list available across the app mostly we make the ArrayList as static object and refer it with its class name to access the data. But if we were to utilize spring autowiring feature at its best, define the List as a spring bean like below

@Configuration
public class Config{

//.. other beans

@Bean("studentTypes")
public List<String> studentTypes(){
 return new ArrayList<>();
}

//.. other beans

}

And autowire it as below across the application

@Service
public class SomeService{

@Autowire
@Qualifier("studentTypes")
List<String> studentTypes;

//.. Use it as per your requirement.
} 

Depending on the scenario we can use any Collections object from the collections framework.

Always prefer private access specifier while writing Instance variables

Always make sure you define all the member variables as private. In case if you want to access them in another class then expose them through a public methods e.g setters, getters.

public class Student{

private String name;
private Integer age;

public String getName(){
  return this.name;
}

public String setName(String name){
  this.name = name;
}


// ..TODO: same applies for other fields
}

Java 8 functional interface

Java 8 functional interface is a great addition, no doubt about it. But if you keep writing inline implementations then code would become messy after a while. So if you keep lambdas separately and use its reference whenever required, then the code look cleaner as below.

Predicate<Integer> isAdult = (x) -> x.getAge() > 18;

List adultStudents = studentsList.stream().filter(isAdult).collect(Collectors.toList());

Write less comments, more self expressive terminology

Lets take above example. it can be written as below which is perfectly valid. but for someone else reading it makes it difficult to understand without comment.

Everytime some new changes happens to the below code should be updated in comments otherwise comment says something and code says something else, which causes confusions.

// Filter adult students
List as = list.stream().filter((a) -> a.getAge() > 18).collect(Collectors.toList());

but if we can write code in a self explanatory way, even if the code changes also we would keep the expressiveness without bothering to update comments.

Predicate<Integer> isAdult = (x) -> x.getAge() > 18;

List adultStudents = studentsList.stream().filter(isAdult).collect(Collectors.toList());

Split Application into multiple maven modules

Earlier we used to write entire application in one maven project, but maintaining such projects is a huge challenge. Separate packaging keeps application maintainable till some level but when the application grows bigger, then packaging alone cannot help.

So while creating the application itself we should split the application into multiple modules. Let’s assume that we were about to write a student management application and it has below modules

  1. student profile creation
  2. student profile edit
  3. Marks entry
  4. Marks edit

Now, lets split the application into modules.

Create a Module for all the controllers

Controller module will expose student profile creation and edit endpoints. And it’ll need dtos module and Services module as dependency.
/api/v1/profile/create
/api/v1/profile/edit

… and so on

Create a Module for all the dtos

dto module will hold plain pojo classes like StudentProfile, Marks etc. We might need very less beans for our little app, but as the application grows there will be 100’s of DTO’s.

Create a Module for all the Services & Rest calls (Which calls other services)

Service module is where we write business logic, and communicate with repositories module to interact with DB. Also If we have any requirement to call other APIs, then this is the right module to do so.

Create a Module for all the Repositories (DB interaction code)

Repositories module will have only DB interaction code like Entity Beans, Repositories and other SQL query executions etc.

This way we can segregate our application code properly to make the application loosely coupled and maintainable. This doesn’t make application bug free but allows us to identify the root causes easily.

Thanks for reading the article, Hope you find it interesting.