Using a builder can solve the issue of having to many parameters in a constructor when all the fields are not mandatory. It also takes away the problems with having multiple constructors for different purposes. Note that a builder still should have a constructor with the mandatory fields that always needs to be set.
At the bottom, some of the classes can have up to 30 parameters, 28 of which are just being passed into the super constructor.
There can be multiple constructors in a class. However, the parameter list of the constructors should not be same. This is known as constructor overloading.
This method has four parameters: the loan amount, the interest rate, the future value and the number of periods.
The Builder Design Pattern might help. Consider the following example
public class StudentBuilder
{
private String _name;
private int _age = 14; // this has a default
private String _motto = ""; // most students don't have one
public StudentBuilder() { }
public Student buildStudent()
{
return new Student(_name, _age, _motto);
}
public StudentBuilder name(String _name)
{
this._name = _name;
return this;
}
public StudentBuilder age(int _age)
{
this._age = _age;
return this;
}
public StudentBuilder motto(String _motto)
{
this._motto = _motto;
return this;
}
}
This lets us write code like
Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
.name("Spicoli")
.age(16)
.motto("Aloha, Mr Hand")
.buildStudent();
If we leave off a required field (presumably name is required) then we can have the Student constructor throw an exception. And it lets us have default/optional arguments without needing to keep track of any kind of argument order, since any order of those calls will work equally well.
Can you encapsulate related parameters inside an object?
e.g., if parameters are like
MyClass(String house, String street, String town, String postcode, String country, int foo, double bar) {
super(String house, String street, String town, String postcode, String country);
this.foo = foo;
this.bar = bar;
then you could instead have:
MyClass(Address homeAddress, int foo, double bar) {
super(homeAddress);
this.foo = foo;
this.bar = bar;
}
What you probably want to do is have a Builder class. Then you would do something like this:
MyObject obj = new MyObjectBuilder().setXxx(myXxx)
.setYyy(myYyy)
.setZzz(myZzz)
// ... etc.
.build();
See page 8 and following of this Josh Bloch presentation (PDF), or this review of Effective Java
Well, using the builder pattern might be one solution.
But once you come to 20 to 30 parameters, I would guess that there is a high relationship between the parameters. So (as suggested) wrapping them into logically sane data-objects probably makes the most sense. This way the data object can already check the validity of constraints between the parameters.
For all of my projects in the past, once I came to the point to have too many parameters (and that was 8 not 28!) I was able to sanitize the code by creating a better datamodel.
As you are constrained to Java 1.4, if you want DI then Spring would be a very decent option. DI is only helpful in places where the constructor parameters are services or something that does not vary during runtime.
If you have all of those different constructors due to the fact that you want variable options on how to construct an object, you should seriously consider using the Builder pattern.
The best solution is not having too much parameters in the constructor. Only parameters really needed in constructor, are params that are need to correctly initialize the object. You can have constructors with multiple parameters, but also have a constructor with only the minimum parameters. The additional constructors call this simple constructor and after that setters to set the other params. This way you can avoid the chain-problem with more and more params, but also have some convenience-constructors.
I can really recommend using Immutables or POJOBuilder when using the builder pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With