I have an algorithm with mostly invariant parts that needs to be reused within one class so as to stay DRY.
Code duplication with repeating method structure
public void save(String key, int value) {
try {
if (isValidWrite()) {
// Only variable part
editor.putInt(key, value);
if (!writeOnDisable){
write(editor);
Log.v(TAG, "Saved " + key + " | "+ value);
}
}
} catch (Exception e) {
Log.e(TAG, "save", e);
}
}
public void save(String key, String value) {
try {
if (isValidWrite()) {
// Only variable part
editor.putString(key, value);
if (!writeOnDisable){
write(editor);
Log.v(TAG, "Saved " + key + " | "+ value);
}
}
} catch (Exception e) {
Log.e(TAG, "save", e);
}
}
Solution?
- The template method pattern is not applicable, because it requires sub-classing.
- Strategy – do I really need to create an interface and provide different implementations to pass into a generalized method as a delegate? Maybe I’m just complaining about proper support for delegates in Java.. (in C# could just use a generic Action<>)
2
protected void applyParameters(Editor editor, Object [] parameters) {
for(Object param : parameters) {
if(param instanceof Integer) {
editor.putInt(key, param);
} else if (param instanceof String) {
editor.putString(key, param);
} else {
// case for unknown type?
}
}
}
public void save(String key, Object ... params) {
try {
if (isValidWrite()) {
if(params != null)
applyParameters(editor, params);
if (!writeOnDisable){
write(editor);
Log.v(TAG, "Saved " + key + " | "+ value);
}
}
} catch (Exception e) {
Log.e(TAG, "save", e);
}
}
Try this. Essentially, you cannot generalize “putInt” and “putString”, but you can at least extrapolate them into their own method. Just provide a case for parameters you do not recognize as valid.
This is al alternate solution, you expose two methods, one for ints
and one for Strings
.
A private method receives both kind of values and decides what to save.
public void save(String key, int value) {
save(key, new Integer(value), null); // pass null in String param
}
public void save(String key, String value ) {
save(key, null, value); // pass null in Integer param
}
private void save(String key, Integer intVal, String strVal){
String strToLog="";
try {
if (isValidWrite()) {
if ( intVal != null) {
editor.putInt(key, intVal);
strToLog = intVal.toString();
} else if ( strVal != null) {
editor.putInt(key, strVal);
strToLog = strVal;
}
if (!writeOnDisable){
write(editor);
Log.v(TAG, "Saved " + key + " | "+ strToLog);
}
}
} catch (Exception e) {
Log.e(TAG, "save", e);
}
}
1