在这种情况下,我应该使用哪种模式/解决方案来避免instanceof
?我搜索了一下,发现访客模式是要走的路,但我不认为这适用于这种情况。还有其他解决方案,比如添加isTestable()方法来表达黑客解决方案,我正在寻找一种标准的方法。
public class PhraseOwner(){
List<Phrase> phrases;
public void switchTestMode(){
for(Phrase phrase : phrases){
if(phrase instanceof Testable())
(Testable)phrase.switchTestMode();
}
}
}
public interface Phrase{
//STUFF
}
public interface Testable{
public void switchTestMode();
}
我有两种类型,即仅实现Phrase
接口的类和已实现Phrase
和Testable
接口的类。
public class A implements Phrase,Testable{
public void switchTestMode(){
//stuff
}
}
public class B implements Phrase{
//stuff
}
}
答案 0 :(得分:1)
访问者为不同或相同的对象层次结构收集相同类型的操作 在你的情况下,它不是,因为其中一个对象错过了测试的概念。
由于Phrase
不是Testable
(或相反),我不会生成List<Phrase>
类型。
不要将苹果与橙子混合。收集的仿制药是为避免这种情况而发明的。
您必须通过从List<Phrase>
识别List<Testable>
来重新考虑您的代码设计,或者如果存在链接,则通过构建分层链接来改进多态性。
答案 1 :(得分:1)
一种解决方案是为不可测试的短语创建一个抽象类,只需让.switchTestMode()
不做任何事情:
public abstract class NonTestablePhrase
implements Phrase, Testable
{
@Override
public final void switchTestMode()
{
}
}
然后你可以声明public class B extends NonTestablePhrase
。
答案 2 :(得分:0)
显而易见的答案是向两个类添加一个布尔值,表示短语是否可测试。如果它是可测试的,它还应该实现Testable接口。然后,您可以检查任何短语的布尔值,而无需事先知道它是否是可测试的类。但是,我会在初始化程序中使用instanceof()来设置布尔值!我也会重载初始化程序,因此通常将布尔值设置为False,除非特别实例化为True。
答案 3 :(得分:0)
或者,您可以让可测试和不可测试的类分别实现可测试或不可测试的接口,同时根据多态性允许您在任一接口上调用方法'switchtestmode'!您不必测试实例,但是您必须为所有不可测试的类实现非可测试的接口(对您来说可能或可能不可用的东西)
答案 4 :(得分:0)
使用Class#isAssignableFrom()
可以避免使用instanceof
:
if (Testable.class.isAssignableFrom(phrase.getClass())) {
((Testable) phrase).switchTestMode();
}
不可否认,这可能被认为是“语义学”,因为虽然技术上它实现了目标,但它或多或少地做同样的事情。