根据Java中接口的实现处理对象
我一直在寻找设计思路来解决
Java中的这个问题.
我正在使用一个库(我无法改变它),对于这个例子,我只是称之为“动物”.它包含一个Animal接口和一堆实现;我需要根据动物的实现调用不同的方法: List<Animal> animals = Service.getAnimals(); for(Animal a : animals) { process(a); } private void process(Animal animal) { if (animal instanceOf Cat) { processCat(animal); } else if (animal instanceOf Dog) { processDog(animal); } else { System.out.println("unsopported animal"); } } 我目前正在通过反射解决这个问题,一个类包含所有“处理器”并使用它来调用它们 String methodName = "process" + Animal getClass().getSimpleName(); //ugh 我正在使用Java 8,我很确定必须有更好的设计来解决这个问题. 任何帮助表示赞赏! 解决方法
如果Animal是一个密封类,也就是说,它不是动态可扩展的,并且具有有限的已知数量的子类,那么在示例中偶然发现的if-instanceof模式是经典的“模式匹配”.
如果Animal是一个你可以控制的类,那么你可以使用Visitor Pattern直接在Animal上创建一个访问方法. 但是,您声明Animal来自外部库,这限制了您可以采取的方法. 您仍然可以使用访问者模式,使所有代码都负责在单个类中与Animals交互,使用方法重载在运行时解析类型(假设您没有任何泛型问题). 但实际上这就像if-instanceof方法一样不灵活,只会让OO人感觉更好. 因此,采用的方法归结为代码组织,以及对代码库有意义的方法. 老实说,if-instanceof就是我想要的,除非方法/行为的数量开始变得过于复杂. 在这种情况下,我会创建一种注册表,为每种动物类型注册一个处理器. 然后,您可以创建一个简单的类,从注册表中获取Animal类型所需的处理器. 我见过的这种注册表模式在Minecraft中使用了很多,但我不确定它是否在其他地方记录过. 基本上它的使用看起来像这样. void onApplicationStart(){ Registry registry = new Registry(); registry.register(Cat.class,cat -> catProcessor.process(cat)); registry.register(Dog.class,dog -> dogProcessor.process(dog)); registry.registerFallback(Animal.class,ani -> animalProcessor.process(ani)); } 然后,您可以获取注册表以及执行处理的方法. void whenNeeded(Animal animal){ Registry registry = fetchRegistrySomehow(); registry.for(animal.getClass()).apply(animal); } 编辑:故意丢失注册表的实现,因为确切的行为会有所不同,具体取决于您希望如何进行查找,处理类层次结构,何时以及是否应在某些应用程序启动事件后密封注册表. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- java – Hibernate异常:枚举类的未知名称值
- 在Java中重载方法时的奇怪行为
- 无法理解java中的界面
- java – 加载位于“src”maven文件夹中的fxml文件
- java – Oracle是否在JRE 7更新51上查杀了内部网小程序?
- java – ** copy **和** addAll **之间有什么区别吗?
- 如何清除Java HttpServletResponse的屏幕输出
- java – Robolectric启动时反射的NullPointerException –
- java – 扩展现有的ant路径标记
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05