根据Java中接口的实现处理对象

前端之家收集整理的这篇文章主要介绍了根据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);
}

编辑:故意丢失注册表的实现,因为确切的行为会有所不同,具体取决于您希望如何进行查找,处理类层次结构,何时以及是否应在某些应用程序启动事件后密封注册表.

原文链接:https://www.f2er.com/java/121488.html

猜你在找的Java相关文章