1

I have researched on this topic and found out that assigning fields via constructor is a better practice rather than setter. But, what if I have an object with 10 fields? That would lead to big constructors and would that still be considered good practice?

For example:

   public DefaultAccount(Long id, String name, String surname, String username, String password, Role role) {
    this.id = id;
    this.name = name;
    this.surname = surname;
    this.username = username;
    this.password = password;
    this.role = role;
   }

This constructor looks big to me.

Bravo
  • 1,944
  • 4
  • 29
  • 53
  • It is not bad practice. You constructor is not that big as is contains no intelligence. – Serge Ballesta Nov 26 '14 at 13:26
  • What if my constructor has twice more fields? Would that still be normal? – Bravo Nov 26 '14 at 13:28
  • A constructor can assign all the fields. If you find normal that a single class has that many fields (and it can be normal), you can have a contructor that assigns them all. But you should then have another constructor with less parameters ... – Serge Ballesta Nov 26 '14 at 13:37
  • I also posted a question of this kind and it was downvoted to hell because they said the answer would be opinion based. Some may think this in this case as well, but I don't :). +1 from me! – Willi Mentzel Nov 26 '14 at 14:05
  • 1
    @chsdk This is not the entirely same problem! Here it is about size not the principle when to use a constructor at all. – Willi Mentzel Nov 26 '14 at 14:06

6 Answers6

2

One problem with constructors that take many parameters (or having multiple constructors that take different sets of parameters) is the mistakes that can happen when several parameters have the same type. Consider from your example how easy it could be to get the order of name and surname the wrong way around.

A solution to this could be to use the Builder pattern.

The following is a comprehensive look at how this works: the builder pattern in practice and the following stack-overflow question covers it pretty well too: when would you use the builder pattern

Community
  • 1
  • 1
stk_sfr
  • 619
  • 5
  • 18
1

Actually having big amount of parameters in any of methods (includes constructors) is a bad practice.

First of all i see DefaultAccount constructor with fields not directly related with Account.

You should extract for example name and surname to another (User?) class and so on.

robocoder
  • 113
  • 1
  • 9
1

In my opinion it depends on the situation. The example you listed is a pretty simple class with only simple types. I would consider that all right. However, I am not really sure about your statement considering setters. But there is something you might have to consider:

If you are working with some of the bigger frameworks (Spring, Hibernate...) a lot of them will instantiate objects using a default constructor (like new Person()) and then call setters for fields. They will throw exceptions if something is not available.

Having a constructor like the one you listed is fine. But setters would be needed anyway. If they get complex, consider refactoring the class. Maybe too many dependencies are needed. Maybe instead of having 10 parameters you can encapsulate them in another object (for example a configuration).

Try to not make fields public. When at some point you have to check for a certain condition in a setter and your field was public, you'll spend some time refactoring that. Check for preconditions in setters if needed and throw exceptions.

I also found this question on stackoverflow, which takes the question about setters a bit further: Java setting private fields inside constructors

Community
  • 1
  • 1
Slomo
  • 1,224
  • 8
  • 11
1

If not all the parameters are mandatory, then consider using Builder pattern as suggested in Item #2 of Effective Java by Joshua Bloch, which says...

Instead of making the desired object directly, the client calls a constructor (or static factory) with all of the required parameters and gets a builder object. Then the client calls setter-like methods on the builder object to set each optional parameter of interest. Finally, the client calls a parameterless build method to generate the object, which is immutable.

saharsh-jain
  • 486
  • 7
  • 11
1

In my opinion the most effective way would be to break the problem down to as many as possible classes like so:

public DefaultAccount(Long id, String name, String surname, User user) 
{
    this.id = id;
    this.name = name;
    this.surname = surname;
    this.user = user;
}

// From second class User
public User(String username, String password, Role role)
{
    this.username = username;
    this.password = password;
    this.role = role;
}

This way you avoid enormous constructors and you improve code maintainability and readability.

You can also use configuration classes like described here.

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
0

getters and setters are used when you have multiple classes, and that too when your fields are private(or protected and required to get accessed from some another package). If you only have a single class you don't need to create getters and setters, you can assign the values to objects directly(given that you don't want to assign them in your constructor)

Sarthak Mittal
  • 5,794
  • 2
  • 24
  • 44