views:

231

answers:

3

These two functions have basically the same code. How can I factor it out?

public static String[] removeSuffix(String gA, String gB) {

     String[] results = new String[2];
     results[0] = gA;
     results[1] = gB;

     if (gA.equals("") || gB.equals("")) {
      return results;
     }

     if (gA.charAt(gA.length() - 1) == gB.charAt(gB.length() - 1)) {
      return removeSuffix(gA.substring(0, gA.length() - 1), gB.substring(0, gB.length() - 1));
     }
     else {
      return results;
     }
    }


    public static String[] removePrefix(String gA, String gB) {

     String[] results = new String[2];
     results[0] = gA;
     results[1] = gB;

     if (gA.equals("") || gB.equals("")) {
      return results;
     }

     if (gA.charAt(0) == gB.charAt(0)) {
      return removePrefix(gA.substring(1), gB.substring(1));
     }
     else { //if the first two chars are not equal
      return results;
     }
    }
+1  A: 

move the differing part (the last if statement) into two seperate methods.

move that methods into to classes.

rename both methods to the same name

make the now common signature of the new classes an interface.

move the content of the original methods to a new method, which takes the instance of the new class as an additional parameter.

Jens Schauder
I think I was hit over the head with the "OOP" stick.
pst
if-then's and switches can usually be removed by polymorphism, but in this case, seems kinda silly to go through all that trouble.
Gary
The question posed was: "How?" not "If?"
Jens Schauder
+1  A: 

One solution would be to move the logic of both methods to a new common method and to use a switch for the specifics parts of the logic. Then, call this method from removeSuffix() and removePreffix() passing the switch as additional parameter:

public static String[] removeSuffix(String gA, String gB) {
    return removeSufOrPreFix(gA, gB, Direction.SUFFIX);
}

public static String[] removePrefix(String gA, String gB) {
    return removeSufOrPreFix(gA, gB, Direction.PREFIX);
}

private static String[] removeSufOrPreFix(String gA, String gB, Direction direction) {

    //common code
    ...

    if (Direction.PREFIX.equals(direction)) {
         // custom code
         ...
    } else if (Direction.SUFFIX.equals(direction)) {
         // custom code
         ...
    }

}
Pascal Thivent
This would be my choice. Additionally, I would also remove the recursive calls. If I understand the functions correctly they remove the common characters at the end and the beginning of both strings.Loop over one string while comparing its first/last n characters with the other using .startsWith()/.endsWith() to find the number of common characters. Return the remaining parts of the strings.
Kwebble
@Kwebble agreed!
Pascal Thivent
+1  A: 

Refactored with a common search method that finds the last match postion (not meant to be compilable, all psuedocoded. And no guarantees about the absence of 1-off errors;):

Since I did this in a hurry, a few notes - It's probably more efficient to do all the computation with raw char[]'s and indexes, if you're dealing with data big enough where that matters. But it's going to be way better than creating a new string at each iteration. Also the trick of having the suffix just match by reversing and calling prefix isn't so efficient either, I suppose you could have the position match function take a boolean to decide whether to go up or down, if that bothered you.

public static String[]removePrefix(gA,gB)
{
    int lastPrefix=matchPosition(gA,gB);
    return new String[]{ ga.subString(lastPrefix), gb.substring(lastPrefix)};
}

public static String[] removeSuffix(gA,gB)
{
    String[] matchedPrefixes=removePrefix(gA.reverse(), gB.reverse());
    return new String[] { matchedPrefixes[0].reverse(), matchedPrefixes[1].reverse();}
}
private static int matchPosition(ga,gb)
{
    // most advanced position at which forward match is found
    int lastMatch=0;
    int ln_a=ga.length();
    int ln_b=gb.length();   
    for (int i = 0; i<Math.min(ln_a, ln_b); i++)
 {
     if (ga.get(i)!=gb.get(i)) break;
     i++;
 }
    return i;
}
Steve B.