3

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<>)
asked Feb 21, 2013 at 13:56
2
  • 1
    If you can't subclass your own class, maybe you can make the method generic and make editor.put() generic to match? Commented Feb 21, 2013 at 14:03
  • @KilianFoth that would work if I had access to editor source, but it happens to be part of Android framework.. And it would probably require a bunch of type-checking if statements, which impacts sense of elegance Commented Feb 21, 2013 at 14:07

2 Answers 2

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.

answered Feb 21, 2013 at 14:08
1

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);
 } 
}
answered Feb 21, 2013 at 15:40
1
  • Thanks! I actually have additional save methods with more types, which makes me prefer Neil's implementation. Commented Feb 21, 2013 at 15:59

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.