Refactoring Long Parameter List in Constructors (Java)

Long list of parameters in constructors are like ducks following their mother! And ducks are smelly & dumb 😂

Say you come across a class named PollutantEntry that has a long parameter list in the constructor:

There are many problems with such parameter lists:

a) The caller code that invokes the constructor is often unreadable. This one is certainly not pretty code:

(Check the overloaded constructors in java.util.Date for example here.)

b) Many of the fields are often optional. Trying to take into account optional parameters through overloaded constructor calls make it only worser with even 8–10 overloaded constructors like this:

Again, not at all nice.

c) When there is validation code involved, the constructor method body can become quite big & complex with high cyclomatic complexity.

You’ll often see clumps of parameters that are always passed & used together (“data clumps”) — that’s another smell.

Bottom-line: For sure, such code smells bad and needs fixing.

There are a couple of approaches for dealing with “long parameter list in constructors” smell.

Option 1: Use builder pattern

Instead of passing the parameters as arguments, construct an object by calling the methods by introducing the Builder pattern. In fact, this refactoring is so easy and common that the IDEs even automate it. Here is the example from IntelliJ IDEA:

Select the constructor with long parameter list -> “Refactor” -> “Replace Constructor with Builder…”

And choose the “Refactor” in the box that pops up:

That’s it — two clicks and you have a builder class created for you:

What’s more, the caller code gets automatically replaced with the call to the builder!

Not bad, but if you ask me, this still sucks! It’s too long to read now — it looks more like a long Cobra slithering in the code and snakes smell bad as well!

Option 2: Refactor data clumps with abstractions

Let’s take a look at the original PollutantEntry now. There are three logical entities there — location, time, and pollutant name cum readings. Of these, location & pollutant details could be made as separate abstractions. Let’s do that:

Hmm, this does get rid of the long parameter list in the constructor and looks elegant. But can we do better?!

Option 3: Creating Abstractions and Use Builder

In this approach, let’s create the abstractions and use the Builder pattern, as in:

In this case, we don’t have a constructor (or make the constructor private) and choose a static nested Builder class. Now the caller code looks like this:

Ah, I love this — short, sweet and elegant — as any code should be :-)

An example of use of Builder pattern in Java class library is here:

Nice, isn’t it? Imagine providing a constructor for Calendar with so many options like day, month, year, timezone, and what not. Instead, this builder pattern nicely exposes the relevant fields as methods that we can set as needed.

Summary

Long parameter list in constructor is a well-known design smell. To address this smell, don’t look for overloaded constructors as a solution — I would say that’s another smell! Rather, look out for data clumps in the parameters are create abstractions. Also check if introducing Builder pattern can help. Better still, see if you can use both options — introducing abstractions and Builder pattern — that helps refactor this smell into cleaner code.

(Written by Ganesh Samarthyam, Co-Founder, KonfHub Technologies LLP)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
KonfHub

KonfHub is the one-stop platform to create and host tech events. Create the event in under 30 seconds, gamify & amplify for audience engagement!