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:
- 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 providetitle,optionTypeandmessageTypewhen I actually only want to provide an icon. - Specify an overloaded method for each combination of optional parameters.
- Introduce a new parameter object
Optionsto encapsulate all optional parameters and only provide a method with and without such anOptionsparameter.
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.
saveTomethod - it could simply be a setter on thepropertyObject.saveToandupdateoperations, 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 viasaveToorupdate. The possible actions would be COMMENT_OUT (in the written file), DELETE (from the written file) or NOTHING (leave them in the written file).updateandoverwritemethods 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 callingupdate. But the idea is good and I like the fluent naming. I should consider this naming style for MissingKeyAction, too.