简体   繁体   中英

Refactor similar methods to a generic method in Java

I have three similar classes for different types.

public class IntClass {
    private int p1;  private int p2;
    IntClass(int p1, int p2) { this.p1=p1; this.p2=p2; }
    int getP1() { return p1; }
    int getP2() { return p2; }
}
public class DoubleClass {
    private double p1;  private double p2;
    DoubleClass(double p1, double p2) { this.p1=p1; this.p2=p2; }
    double getP1() { return p1; }
    double getP2() { return p2; }
}
public class StringClass {
    private String p1;  private String p2;
    StringClass(String p1, String p2) { this.p1=p1; this.p2=p2; }
    String getP1() { return p1; }
    String getP2() { return p2; }
}
public class C4 {
    ...
    private IntClass c1;
    private DoubleClass c2;
    private StringClass c3;
    ...
    IntClass getIntClass() { return C1; }
    DoubleClass getDoubleClass() { return C2; }
    StringClass getStringClass() { return C3; }
    ...
}

Somewhere else in codebase, I have following snippet of code with 3 similar methods.

...
int a = getInt(C4::getIntClass, boolValue);
double b = getDouble(C4::getDoubleClass, boolValue);
String c = getString(C4::getStringClass, boolValue);
...
private int getInt(Supplier<IntClass> executable, boolean boolValue) {
    ...
    return boolValue? executable.get().getP1(): executable.get().getP2();
}
private double getDouble(Supplier<DoubleClass> executable, boolean boolValue) {
    ...
    return boolValue? executable.get().getP1(): executable.get().getP2();
}
private String getString(Supplier<StringClass> executable, boolean boolValue) {
    ...
    return boolValue? executable.get().getP1(): executable.get().getP2();
}

I wanted to write a generic method getValue in replacement of getInt , getDouble , getString . How can we do so?

Edit:- Cant make generic Class for IntClass , DoubleClass , StringClass as they serve some other usecase as well and are in different package library. Just wanted to refactor code at my end by writing a common generic method and removing similar redundant code. Just a thought.! Any suggestions specific to usecase would be appreciated.

Try this:

public class GenericClass<T> {
    private T p1;
    private T p2;
    GenericClass(T p1, T p2) {
        this.p1=p1;
        this.p2=p2;
    }
    T getP1() { return p1; }
    T getP2() { return p2; }

}
    private T getValue(Supplier<GenericClass<T>> executable, boolean boolValue) {
        return boolValue ? executable.get().getP1(): executable.get().getP2();
    }

Well you need to start with a generic class and do something like:

public class PairOf<T> {
    private T first;
    private T second;

    public PairOf(T first, T second) { 
        this.first = first;
        this.second = second;
    }

    public T getFirst() { return first; }
    public T getSecond() { return second; }

}

Then you can use this class in place of your specific classes exactly as before.

@Test
  public void test() {
    PairOf<String> pairOfStr = new PairOf<>("abc", "def");
    PairOf<Integer> pairOfInt = new PairOf<>(1, 2);
    PairOf<Double> pairOfDouble = new PairOf<>(1.0, 2.0);
    Assertions.assertEquals(pairOfStr.getFirst(), getValue(pairOfStr, true));
    Assertions.assertEquals(pairOfInt.getFirst(), getValue(pairOfInt, true));
    Assertions.assertEquals(pairOfDouble.getFirst(), getValue(pairOfDouble, true));
  }

  public class PairOf<T> {
    private T first;
    private T second;

    public PairOf(T first, T second) {
      this.first = first;
      this.second = second;
    }

    public T getFirst() {
      return first;
    }

    public T getSecond() {
      return second;
    }

  }

  public <T> T getValue(PairOf<T> t, boolean first) {
    return first ? t.getFirst() : t.getSecond();
  }

With number, you can cast to primitive by method:

getValue(pairOfInt, true).intValue();
    getValue(pairOfDouble, true).doubleValue();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM