My answer is very opinionated.
I would go the same way as one of the StringUtils.getLevenshteinDistance
implementation in StringUtils.
public interface GeneDistance{
public int get();
}
public class GeneDistanceImpl implements GeneDistance{
public int get(){ ... }
}
public class GeneUtils{
public static int geneDistance(Gene g0, Gene g1){
return new GeneDistanceImpl(g0, g1).get();
}
}
Some points for doing it this way
- There might be several distance implementations, so an utility method is more preferable than
g0.distanceTo(g1)
- I can static-import it for a short notation
- I can test my implementation
I can also add this:
class Gene{
// ... Gene implementation ...
public int distanceTo(Gene other){
return distance.get(this, GeneUtils.getDefaultDistanceImpl());
}
public int distanceTo(Gene other, GeneDistance distance){
return distance.get(this, other);
}
}
One of the reasons to make a complex method completely static is the performance. static
keyword is a hint for a JIT compiler that the method can be inlined. In my opinion you s/he don't need to bother about such things unless their method calls are almost instantaneous - less than a microsecond, i.e. a few string operations or a simple calculation. This might be the reason why Levenshtein distance was made completely static in the latest implementation.