Duplicate Code? Introduce Null Object

Table of contents
Reading Time: 3 minutes

One of the most significant code smells is having duplicate code. There are primarily 2 forms of code duplications

  • Explicit – These are the ones where there is blatant copy paste of the code. Methods are repeated within classes and it is easy for the CPD tool of PMD to figure out that lines are copied thus leaving us red faced.
  • Subtle – This is the more dangerous form of duplication in which, though differences appear at a syntactical level, however, the structure and the processing steps are quite the same.

One such form of subtle duplication is checking for null. You would have surely encountered a case like this, which we had in our application

[sourcecode language=”java”]

public void upgradeTheDepartment(UserDepartment department){
User headOfDepartment = getHeadOfDepartment(department);
if ( headOfDepartment != null)
{
SalaryStructure structure = headOfDepartment.getSalaryStructure();
}


}
[/sourcecode]

If you notice, in this case, the UserDepartment has a 1 to 0..1 relationship with the User.

In this simplistic code you would see that we check for user being not null and then on the basis of that do some useful work. Having this null check at one or two places is not an issue. However, it becomes an issue when you need to have this check at several places. This checking for null is a subtle form of code duplication which you should like to avoid. Such a duplication works against simple changes, such as fixes or improvements, and is in violation of the DRY principle.

How do we avoid this?

Wouldn’t it be easy if the code could read like

[sourcecode language=”java”]

public void upgradeTheDepartment(UserDepartment department){
User headOfDepartment = getHeadOfDepartment(department);
SalaryStructure structure = headOfDepartment.getSalaryStructure();


}
[/sourcecode]

Well, at least it looks easy to read without the null check everytime. But wouldn’t this code throw a NPE when the headOfDepartment does not exist.

Introduce the Null Object.

Provide something for nothing: A class that conforms to the interface required of the object reference, implementing all of its methods to do nothing or to return suitable default values. So in our case, we would create a Null User for head of department and always assign it to the department. Hence, whenever the department is created it would have code like this


[sourcecode language=”java”]
public class UserDepartment
{
public UserDepartment()
{
this.setHeadOfDepartment(new NullUser());
}
[/sourcecode]

Introducing a NULL OBJECT simplifies the client’s code by eliminating superfluous and repeated conditionals that are not part of a method’s core logic. Selection and variation are expressed through polymorphism and inheritance rather than procedural condition testing.

Ideally, you would like to introduce the Null Object as an implementation of the interface so that the variation can be easily expressed through polymorphism. In our example with the NullUser headOfDepartment, a call to the salary structure would return a blank salary structure.

The object relationship moves from being optional to mandatory, making the use of the relationship more uniform. If you notice that with implementation, there exists a mandatory relationship between the UserDepartment and User Objects.

Hence remember,

IF an object reference could potentially be null and this reference must be checked before every use and the result of a null check is to do nothing or assign a suitable default value THEN it is better to provide a class derived from the object reference’s type and implement all its methods to do nothing or provide default results and use an instance of this class whenever the object reference would have been null. This would not only help in removing the superfluous Null Checks but would also keep you away from the ever-increasing NPEs.

We write clean code. Even though we might be focussed on complex Enterprise Java and Cloud Computing, Inphina truly believes that great software is simple and clean.

Written by 

Vikas is the CEO and Co-Founder of Knoldus Inc. Knoldus does niche Reactive and Big Data product development on Scala, Spark, and Functional Java. Knoldus has a strong focus on software craftsmanship which ensures high-quality software development. It partners with the best in the industry like Lightbend (Scala Ecosystem), Databricks (Spark Ecosystem), Confluent (Kafka) and Datastax (Cassandra). Vikas has been working in the cutting edge tech industry for 20+ years. He was an ardent fan of Java with multiple high load enterprise systems to boast of till he met Scala. His current passions include utilizing the power of Scala, Akka and Play to make Reactive and Big Data systems for niche startups and enterprises who would like to change the way software is developed. To know more, send a mail to hello@knoldus.com or visit www.knoldus.com

8 thoughts on “Duplicate Code? Introduce Null Object3 min read

  1. Interesting thought. However I so a potential problem when using ORM. Mostly, You’ll want to save the UserDepartment with a potential NullUser.

    Don’t have to do something like
    if (userDepartment.getUser() instanceof NullUser)
    remove the null user

    ?

    1. Hi Andries, You bring an interesting point to the table. But if we have code like -> if (userDepartment.getUser() instanceof NullUser) remove the null user and if this check happens to be at more than a couple of places then we fall back into the same duplicate code trap again. I believe that storing the NullUser with the UserDepartment is not an issue. This would also be helpful when say you would like to retrieve the user department and get the headOfDepartment to do some processing. Now, since you would always NullUser returned with doNothing processing, it would not blow up the code.

      Also if you noticed then we have made the mapping of UserDepartment and User 1:1 instead of 1:0..1, in that case too it would be prudent to save the NullUser with the UserDepartment. So I would store the NullUser with the UserDepartment with the ORM mapping too.

      1. The implication of introducing stub entities into you database might be trickier than you first think.

        When displaying a list of all users, with the headOfDepartment next to it, will again need an “instance of NullUser” check since you’d want to display nothing when it’s a NullUser.

        About the ORM: I’ve thought about it, and if your are using Hibernate, it would be possible to write an UserType that returns NullUser instead of null when no user is found.

        Have you finished a project with this approach?

  2. > When displaying a list of all users, with the headOfDepartment next to it, will again need an “instance of NullUser” check since you’d want to display nothing when it’s a NullUser.

    No actually not, you would call the methods on the NullObject as though it were the actual Not-Null object. The method implementation would be such that you do nothing. I hope that clears that you would not have to check the instance at all.

    We have used this approach on our SaaS project on Google App Engine. We used JPA for abstraction to the datastore.

Comments are closed.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading