2
\$\begingroup\$

I have code like the following, which performs a series of replacements on a string, to convert it to its final form.

public String convertString(String string) {

String convertedString = string;

if( string.contains("something")) {
    convertedString = convertStringA(string);

    return convertedString;
} else if (string.contains("something else")) {
    convertedString = convertStringB(string);

    return convertedString;
} ...

// many more else if blocks

else if (string.contains("something else")) {
    convertedString = convertStringXXX(string);

    return convertedString;
} ...

}

How can I do it better?

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

I'd start with an interface:

public interface Converter {
    boolean canHandle(String inputString);
    String convert(String inputString);
}

and write a few implementations, like SomethingConverter, OtherConverter, etc. An example:

public class SomethingConverter implements Converter {

    public boolean canHandle(final String inputString) {
        return StringUtils.contains(inputString, "something");
    }

    public String convert(String inputString) {
        ...
    }
}

Then put them into a collection:

final List<Converter> converters = new ArrayList<>();
converters.put(new SomethingCoverter());
converters.put(new OtherConverter());

and finally use them:

for (final Converter converter: converters) {
    if (converter.canHandle(inputString)) {
        return converter.convert(inputString);
    }    
}
throw new IllegalArgumentException("Unhandled input: " + inputString); // may not be applicable, depends on the requirements

I've used StringUtils.contains beacuse it's null-safe, it does not throw NullPointerException if the inputString is null

(The code is not tested, feel free to fix the typos if there is any.)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks! It looks much better! I will use your solution. :) \$\endgroup\$
    – nerd
    May 11, 2013 at 7:52
3
\$\begingroup\$

Your Algorithm is a little bit too abstract to provide a one size fits all solution.

What does it mean, when a string contains "something" or "something else"? Are they completely different strings like "I know (something)" and "He gave me (something else)"? Or are there similarities like: "Peter knows (something)" and "Joe knows (something else)". So "knows" would be the keyword after which your phrase occurs. "Contains" is somehow a little bit unprecise.

If it is relativly easy to extract the substring you need -perhaps with a regular expression- you could use a HashMap to provide the correct converter with a simple call with the phrase as the key.

public class Converters {

  HashMap<String, Converter> converters=new HashMap<String, Converter>();    

  public Converters(){
      // Fill Hashmap here
  }

  public Converter getConverterFor(String phrase){
      if (!converters.containsKey(phrase)) throw new NoConverterFoundException();
      return converters(phrase);
  }    

}

Converter is here an interface, which all of your converters have to implement. This solution provides easy maintenance - a new Converter needs only one new entry in the HashMap. And no unreadable if-else-whattheeckyouwantelse-blocks anymore.

But this is only one possible solution. A better solution requires more information on your phrases.

\$\endgroup\$
1
  • \$\begingroup\$ Strings are completely different. \$\endgroup\$
    – nerd
    May 11, 2013 at 7:52

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.