Skip to content

Instantly share code, notes, and snippets.

@g0t4
Created October 24, 2014 15:52
Show Gist options
  • Save g0t4/f5534eb5c51b267bc1e1 to your computer and use it in GitHub Desktop.
Save g0t4/f5534eb5c51b267bc1e1 to your computer and use it in GitHub Desktop.
Demonstrating one off extension functions in Kotlin for improving readability
public class ArgumentBuilder(private val runnerParameters: Map<String, String>) {
public fun build(): List<String> {
return arrayListOf<String>()
.addIfSet("--Project", RunnerSettings.PROJECT_FILE)
.addIfSet("--Output", RunnerSettings.OUTPUT)
.addFlagIfSet("--Flag1", RunnerSettings.FLAG_1)
.addFlagIfSet("--Flag2", RunnerSettings.FLAG_2)
.addFlagIfSet("--Flag3", RunnerSettings.FLAG_3)
.addMultipleIfSet("--InputFiles", RunnerSettings.INPUTS)
}
private fun MutableList<String>.addFlagIfSet(argument: String, setting: String): MutableList<String> {
if (runnerParameters.doesNotContainKey(setting)) {
return this;
}
add(argument)
return this
}
private fun MutableList<String>.addIfSet(argument: String, setting: String): MutableList<String> {
val value = runnerParameters.get(setting)
if (value == null) {
return this;
}
add(argument)
add(value)
return this;
}
private fun MutableList<String>.addMultipleIfSet(argument: String, setting: String): MutableList<String> {
val value = runnerParameters.get(setting)
if (value == null) {
return this;
}
val values = value
.splitOnLineBreaks()
.filterEmptyLines()
if (values.isEmpty()) {
return this;
}
add(argument)
addAll(values)
return this;
}
}
@g0t4
Copy link
Author

g0t4 commented Oct 24, 2014

Revision 1 is before, Revision 2 is after the refactoring. Note there are two components, first using extension functions on a MutableList and second creating a fluent interface by returning the type being acted upon (MutuableList).

Focus on the readability of the build method. One could argue the fluent aspect is less readable within the extension functions, in that case just remove the fluent aspect and still have:

val arguments = ArrayList<String>()
arguments.addIfSet("--Project", RunnerSettings.PROJECT_FILE)
arguments.addIfSet("--Output", RunnerSettings.OUTPUT)
arguments.addFlagIfSet("--Flag1", RunnerSettings.FLAG_1)
arguments.addFlagIfSet("--Flag2", RunnerSettings.FLAG_2)
arguments.addFlagIfSet("--Flag3", RunnerSettings.FLAG_3)
arguments.addMultipleIfSet("--InputFiles", RunnerSettings.INPUTS)
return arguments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment