gpt4 book ai didi

java - 根据对象在 Java 中的接口(interface)实现来处理对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:57:52 26 4
gpt4 key购买 nike

我一直在寻找用Java解决这个问题的设计思路。

我正在使用一个库(我无法更改它),对于这个例子,我将称之为“动物”。它包含一个Animal 接口(interface),以及一堆实现;我需要根据我得到的 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 来自外部库,这限制了您可以采用的方法。

您仍然可以使用访问者模式,将负责与动物交互的所有代码保留在一个类中,使用方法重载在运行时解析类型(假设您对泛型没有任何问题)。

但实际上这与 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 - 根据对象在 Java 中的接口(interface)实现来处理对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50690523/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com