2

I am currently developing on a small library allowing to read and write Java .properties files while retaining all the formatting (comments, whitespace, etc.): https://github.com/hupfdule/apron

This library has a saveTo method to write the content of such a PropertyFile to a file or an OutputStream. At the moment this saveTo allows a Charset to be given as parameter to specify the encoding (if the default UTF-8 should not apply). This leaves me with the following method signatures:

saveTo(File)
saveTo(File, Charset)
saveTo(OutputStream)
saveTo(OutputStream, Charset)

However there are corresponding update and overwrite methods so there are actually 6 more methods (update does not allow an OutputStream):

update(File)
update(File, Charset)
overwrite(File)
overwrite(File, Charset)
overwrite(OutputStream)
overwrite(OutputStream, Charset)

Now I need to introduce another optional Parameter of the enum-type MissingKeyAction.

The question is: How to change the method signatures to allow, but not require the optional parameters.

I see the following approaches at the moment:

  1. Provide only some parameter-combinations. This is similar to e.g. JOptionPane#showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon) where I need to provide title, optionType and messageType when I actually only want to provide an icon.
  2. Specify an overloaded method for each combination of optional parameters.
  3. Introduce a new parameter object Options to encapsulate all optional parameters and only provide a method with and without such an Options parameter.

The 1st approach is not user friendly in my opinion as the consumer of the API needs to specify some parameter values even though he would like to just use the default for them.

The 2nd approach requires a lot of tedious work for specifying all method combinations and I would end up with lots of overloaded methods. This would get even worse if I need to introduce another parameter!

The 3rd approach seems to be the best in my opinion as it does not clutter the interface, allows the API user to provide only the Options where he does not want to rely on the default and it is even upward compatible as I do not need to change the method signatures when I need to add another optional parameter in the future.

If I provide a fluent interface for the Options class the client code could look something like this:

import java.io.File;
import static java.nio.charset.StandardCharsets.UTF_8;

public class TestApron {
  public static void main(String[] args) {
    final Options apronOptions= Options.create()
      .with(UTF_8)
      .with(MissingKeyAction.DELETE);
    final PropertyFile propertyFile= new PropertyFile();
    propertyFile.setValue("myKey", "myValue");
    propertyFile.saveTo(new File("someFile.properties"), apronOptions);
  }
}

As I already mentioned above I consider this new Options parameter as the best solution and am willing to implement this.

However I want to hear some other opinions on that topic and if there are even some other possibilities for addressing this problem I haven't thought of yet.

  • Is it actually the case that behaviour such as "reaction to a missing key" should affect only this one save action and might afterwards be entirely different - or is this something that you'd probably want to work consistently during te life time of the object? If so, there's no reason why this has to be an option to the saveTo method - it could simply be a setter on the propertyObject. – Kilian Foth Sep 24 '18 at 9:30
  • @KilianFoth It is only relevant to the saveTo and update operations, but not the current PropertyFile object. The meaning is how to handle key-value-pairs that exist in this object, but not in the .properties file that is updated via saveTo or update. The possible actions would be COMMENT_OUT (in the written file), DELETE (from the written file) or NOTHING (leave them in the written file). – radlan Sep 24 '18 at 9:34
  • Have you considered only using a "saveTo" method, with an enumerator parameter telling it what to do in case of existing file? Such as saveTo(WhenExisting.Override, theFile)? You'd simply have combinations of the one method at that point. – Neil Sep 24 '18 at 10:36
  • @Neil I like the idea. I will take it into account. This would allow me to make the update and overwrite methods private. There is only one (small) drawback. I am not able to throw an Exception if the user explicitly wants to update a file, but that file is missing. I could tackle this by adding an enum value like WhenExisting.OnlyUpdate, but that could be a bit too complicated in contrast to just calling update. But the idea is good and I like the fluent naming. I should consider this naming style for MissingKeyAction, too. – radlan Sep 24 '18 at 13:39
  • 1
    Builder design pattern is often recommended as a healthier alternative to telescoping constructors. – Nick Alexeev Sep 24 '18 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.