instanceof vs布尔类型检查

use*_*451 2 java

我有一个名为Section和MapSection的接口,该接口扩展了section。我有一个Sections列表,如果它是MapSection,我需要做一些额外的处理。我可以通过两种方式处理此问题。我可以将一个boolean isAMapSection()添加到Section接口,但是如果添加更多类型,则会导致大量isA .. 我可以想到的另一种方法是instanceof check,但是我的OOP感觉也不太好。

curSection instanceof MapSection
Run Code Online (Sandbox Code Playgroud)

其中哪一种是正确的方法?还是有另一种方法?

Hov*_*els 5

正如上面奥利弗·查尔斯沃思(Oliver Charlesworth)的评论所提到的,您可以使用“ 访问者设计模式”(Visitor Design Pattern)使您的代码根据所涉及的类型执行不同的操作,而不必使用一堆instanceof或class equals。

例如,假设您有两个类似的接口,Section和MapSection,其中咧嘴笑的将为MapSection提供另一种方法:

interface Section {
   void someMethod();
   void accept(SectionVisitor visitor);
}

interface MapSection extends Section {
   void additionalProcessingMethod();
}
Run Code Online (Sandbox Code Playgroud)

我们还将为Section提供accept(...)一种方法,以允许类型为SectionVisitor的Visitor的界面执行以下操作:

interface SectionVisitor {
   void visit(Section section);
   void visit(MapSection mapSection);
}
Run Code Online (Sandbox Code Playgroud)

visit方法将保存代码,该代码根据传递给它的类型知道要调用的方法。

一个非常简单的具体示例如下所示:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class VisitorTest {
   public static void main(String[] args) {
      Random random = new Random();
      List<Section> sectionList = new ArrayList<>();
      for (int i = 0; i < 10; i++) {
         Section section = random.nextBoolean() ? new ConcreteSection() : new ConcreteMapSection();
         sectionList.add(section);
      }

      SectionVisitor visitor = new ConcreteSectionVisitor();
      for (Section section : sectionList) {
         section.accept(visitor);
      }
   }
}

interface Section {
   void someMethod();
   void accept(SectionVisitor visitor);
}

interface MapSection extends Section {
   void additionalProcessingMethod();
}

interface SectionVisitor {
   void visit(Section section);
   void visit(MapSection mapSection);
}

class ConcreteSection implements Section {

   @Override
   public void someMethod() {
      System.out.println("someMethod in ConcreteSection");
   }

   @Override
   public void accept(SectionVisitor visitor) {
      visitor.visit(this);
   }

}

class ConcreteMapSection implements MapSection {

   @Override
   public void someMethod() {
      System.out.println("someMethod in ConcreteMapSection");
   }

   @Override
   public void additionalProcessingMethod() {
      System.out.println("additionalProcessingMethod in ConcreteMapSection");
   }

   @Override
   public void accept(SectionVisitor visitor) {
      visitor.visit(this);
   }

}

class ConcreteSectionVisitor implements SectionVisitor {

   @Override
   public void visit(Section section) {
      section.someMethod();
   }

   @Override
   public void visit(MapSection mapSection) {
      mapSection.someMethod();
      mapSection.additionalProcessingMethod();
   }

}
Run Code Online (Sandbox Code Playgroud)