在这种情况下,我应该使用什么模式/解决方案来避免`instanceof`?

时间:2014-02-25 07:13:33

标签: java oop instanceof

在这种情况下,我应该使用哪种模式/解决方案来避免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接口的类和已实现PhraseTestable接口的类。

public class A implements Phrase,Testable{
  public void switchTestMode(){
    //stuff
  }
}

public class B implements Phrase{
    //stuff
  }
}

5 个答案:

答案 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();
}

不可否认,这可能被认为是“语义学”,因为虽然技术上它实现了目标,但它或多或少地做同样的事情。