我会尝试总结一下已经给出的观点,并且我同意这些观点。
就个人而言,我不认为有一个“感觉更好”的答案。确实存在一些有效的理由,说明您不应该使用填充了静态方法的实用程序类。
简短的答案是,在面向对象的世界中,您应该使用对象及其所带来的所有好处(封装、多态)。
如果计算基因之间距离的方法不同,则应该(更可能是使用策略模式)为每种变化使用一种Gene类。封装变量。否则,您将最终得到多个if语句。
这意味着如果未来出现计算基因之间距离的新方法,则不应修改现有代码,而是应添加新代码。否则,您可能会破坏已经存在的内容。
您应该告诉您的对象要做什么,而不是询问它们的状态并为它们做出决定。突然之间,您打破了单一职责原则,因为这是多态性。
静态方法可能很容易单独测试,但在后续过程中,您将在其他类中使用此静态方法。当对这些类进行隔离测试时,您将很难做到。或者说根本不行。
我会让Misko说出他的话,这可能比我能想到的更好。
import junit.framework.Assert;
import org.junit.Test;
public class GeneTest
{
public static abstract class Gene
{
public abstract int geneDistance(Gene other);
}
public static class GeneUtils
{
public static int geneDistance(Gene g0, Gene g1)
{
if( g0.equals(polymorphicGene) )
return g0.geneDistance(g1);
else if( g0.equals(oneDistanceGene) )
return 1;
else if( g0.equals(dummyGene) )
return -1;
else
return 0;
}
}
private static Gene polymorphicGene = new Gene()
{
@Override
public int geneDistance(Gene other) {
return other.geneDistance(other);
}
};
private static Gene zeroDistanceGene = new Gene()
{
@Override
public int geneDistance(Gene other) {
return 0;
}
};
private static Gene oneDistanceGene = new Gene()
{
@Override
public int geneDistance(Gene other) {
return 1;
}
};
private static Gene hardToTestOnIsolationGene = new Gene()
{
@Override
public int geneDistance(Gene other) {
return GeneUtils.geneDistance(this, other);
}
};
private static Gene dummyGene = new Gene()
{
@Override
public int geneDistance(Gene other) {
return -1;
}
};
@Test
public void testPolymorphism()
{
Assert.assertEquals(0, polymorphicGene.geneDistance(zeroDistanceGene));
Assert.assertEquals(1, polymorphicGene.geneDistance(oneDistanceGene));
Assert.assertEquals(-1, polymorphicGene.geneDistance(dummyGene));
}
@Test
public void testTestability()
{
Assert.assertEquals(0, hardToTestOnIsolationGene.geneDistance(dummyGene));
Assert.assertEquals(-1, polymorphicGene.geneDistance(dummyGene));
}
@Test
public void testOpenForExtensionClosedForModification()
{
Assert.assertEquals(0, GeneUtils.geneDistance(polymorphicGene, zeroDistanceGene));
Assert.assertEquals(1, GeneUtils.geneDistance(oneDistanceGene, null));
Assert.assertEquals(-1, GeneUtils.geneDistance(dummyGene, null));
}
}