best practice/design pattern other than constructor overloading java

1k Views Asked by At

I have a class which has multiple constructors. Each represent different use cases.

public class ABC {
  public ABC(int x) {
  ...
  }
  public ABC(ArrayList<String> Stringarray) {
  ...
  }
  ..many more constructors..
}

Constructor overloading was the clean solution so far until I encountered same erasure issues from java compiler. For example, I want to add another constructor which end up having same erasure, so I just chose to include a default parameter to work around for now like below:

public ABC(ArrayList<String> stringArray) {
  …
}
public ABC(ArrayList<Integer> integerArray, boolean… sameErasureFlag) {
  …
}

But I have a strong feeling probably having so many constructors is not a good design pattern for this use case.. Maybe there is a better solution or best practice design pattern that is used for such a scenario. I am looking up on the builder pattern, but not sure if that is right/better one. Any recommendations?

6

There are 6 best solutions below

2
M A On

It depends on what exactly the class is doing with the parameters, we don't have the exact details, but one simple thing you can do for generic types is to make your own class generic (and maybe no need to apply a fancy design pattern in that case):

public class ABC<T> {
    public ABC(ArrayList<T> stringArray) {
       …
    }
    …
}


ArrayList<Integer> intList = Stream.of(1, 2, 3)
                                   .collect(Collectors.toCollection(ArrayList::new));
ArrayList<String> stringList = Stream.of("a", "b", "c")
                                   .collect(Collectors.toCollection(ArrayList::new));
ABC<Integer> abc1 = new ABC<>(intList);
ABC<String> abc2 = new ABC<>(stringList);
8
GhostCat On

I have a class which has multiple constructors. Each represent different use cases.

Then the simple answer is: turn each use case into its own distinct class.

The idea that you have multiple unrelated fields in a class, and each "use case" only uses some of them is a clear indication that your class is doing too many things.

Any class or method should do "one thing" only. So, as said: the answer is to stop right there, and instead of adding more things into one class: ask yourself how you could meaningfully rip it apart.

0
Olena Dirych On

Yeah, having many constructors can point out that class breaks Single Responsibility principle. I agree - it's not enough info to make a decision. Builder pattern can work or even abstract factory. However - consider using factory method instead of constructors as adviced J.Bloch:

public ABC of(ArrayList<Integer> integerArray, boolean… sameErasureFlag) {

… }

0
tquadrat On

Is your class really implementing different use cases, each represented by another constructor? Then this is the answer!

If you just want to provide different initialisation paths for your class that otherwise does the same things, no matter of the format of the data you used for initialisation, then having multiple constructors might be the proper thing.

But when exceeding a certain number of constructors (some says 3, others 5 … some extremists say even 1), you have definitely too many of them, and then you should consider the factory pattern, as suggested here. This should be considered definitely – no matter how many constructors you have – when you think about the introduction of 'dummy' parameters to resolve erasure issues. The advantage of the factory pattern is that the factory method's signature is not determined by the parameters list only, you can also choose a different name (ABC.ofIntList(), ABC.ofStringList() and so on …).

0
Cristian On

If you have too many fields in your class I would suggest your design is bad. Some may advice using Builder Pattern. But I think it is better to show more respect to OOP, so I think is better to break your class into multiple classes and use Decorator Pattern.

0
Giorgi Tsiklauri On

I have a strong feeling probably having so many constructors is not a good design pattern..

It depends.

Some people prefer constructors, some - other approaches, but I think you are right, that having a lot of overloaded constructors might be cumbersome to read and maintain.

One alternative to consider is the Static Factory Methods. Lately, a lot of authors suggest favouring static factory methods over constructors.

There are few reasons why you might want to favour them:

They give you better, cleaner and more intuitive readability

You can’t give names to constructors. The constructor name is always the same as the class name; however, you might find useful to use naming, as they will provide way clearer readability.

You can construct and return subtypes

When you use constructor, you can’t vary the type of the constructed object; however, factory method can return objects derived from a super class, which means, that you can decide on what exactly to construct, depending on the input criteria.