Search code examples
javaconstructorinstantiationflagsenum-flags

Passing flags (or not) to a constructor in Java


Having methods with different names for roughly the same task makes sense, for example

  • open(String filename);
  • createThenOpen(String filename); // First create the file with default contents, then process the file.

This naming approach does not work for constructors. Imagine the constructor takes a filename as above. I have various options to handle the two cases:

  1. If-statement in the constructor: if the file does not exist then create it. This is not nice as the behaviour of the constructor is implicit and the caller might create unwanted files instead of opening existing files.
  2. Add a flag to the constructor: MyClass(String filename, boolean createNew). Not very nice because a call like MyClass("hello.txt", true) is cryptic.
  3. Overload so that a single argument always assumes file exists, and the presence of an additional dummy parameter means the file should be created. This is also ugly.
  4. Add a String-flag as in RandomAccessFile(File file, String mode) where mode is "r", "rw" and so on. This feels very clunky for my purposes.
  5. Add an enum-flag similar to Files's copy(Path source, Path target, CopyOption... options). Feels pretty clunky too.
  6. Have constructor that takes no argument and then separate methods like above to be called immediately after the object is created. Not nice as it makes no sense to have an instance of my object without instantiating it using data from the specified file.

Currently I seem to actually favour number (6) above and simply have two methods with different names to be called immediately after a no-parameter constructor. Have I overlooked any options, or is there a "given" approach for these scenarios?

Edit: as pointed out by others below there is a 7th, perhaps most obvious option, of course:

  1. Use factory methods!

Solution

  • Make your constructor with a long list of parameters protected, introduce a lot of public static named createFooWithBar() methods with precise parameter lists that call your constructor.