Reputation: 9759
I have a class called RawReader that reads the bytes of some resource, parses them, then writes files to an output directory.
It makes sense to allow different types to be passed in as the source and destination to the constructor.
However if I overload the constructor that leaves me with 8 different versions. If I wanted to add a third optional argument for example chunkSize
I'd have 16 constructors!
On the other hand I could just have two constructors accepting (Object, Object)
and (Object, Object, int)
. The argument types could be detected and an IllegalArgumentExceptions thrown if they aren't correct.
How are situations like this normally handled in Java?
Upvotes: 3
Views: 235
Reputation: 310980
It makes sense to allow different types to be passed in as the source and destination to the constructor.
Up to a point. However it doesn't make much sense to provide conversions that the caller could just as easily provide himself, especially if it's going to lead to as many as eight constructors. So:
(a) You don't need both String
and File
. Decide on one, and stick to it. I would use File
. That already divides the number of constructors by four.
(b) You don't really need both URL
and InputStream
either, although there are precedents. Getting rid of 'URL' would divide the number by two.
Upvotes: 0
Reputation: 425198
If you find you have constructors with the same signature, you can use factory methods with different names:
public class Foo {
public static Foo createForDir(String dir) {
// create a Foo as you like and return it
}
public static Foo createForUrl(String url) {
// create a Foo as you like and return it
}
}
Upvotes: 0
Reputation: 340883
First of all an idea with (Object, Object, int)
is terrible, don't go that way! You loose strong-typing, IDE assistance and API clarity.
On your place I would restrict the constructor to most obvious/low-level input you can take and provide a builder/factory methods:
RawReader reader = RawReaderBuilder.
withInput(inputStream).
withOutput(someFile).
withChunkSize().
build();
Upvotes: 0
Reputation: 597234
You can use a builder:
Foo foo = new FooBuilder().setFile(..).setChunkSize().build();
Where .build()
invokes a constructor of Foo
that takes the builder and assigns whichever variables are set. Something like that:
public class Foo {
private Foo(FooBuilder builder) {
//get whatever you can find from the builder to fill the state of Foo
}
public static FooBuilder {
private String filename;
private File file;
private InputStream stream;
private int chunkSize;
// getters and setters
public Foo build() {
return new Foo(this);
}
}
}
Upvotes: 3