Template Method in One Class Without Subclasses or Inheritance

delegatesdesign-patternsinheritancejava

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<>)

Best Answer

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.

Related Topic