java - 有没有更好的方法来短路 instanceof 链?

标签 java oop switch-statement instanceof

我的类(class)最初是从几个单独的 addAListener() addBListener()removeAListener 等开始的。这对一个来说还不错类,但当该类被另一个类在内部使用并且扩展的监听器传播出去时,它确实向外爆炸。

一个简单的解决方案是使用单一接口(interface)并使用instanceof 对监听器进行分类:

public interface Listener {
}

public class ListenerA extends Listener {
}

public class ListenerB extends Listener {
}

public class ListenerC extends Listener {
}

List<ListenerA> ofListenersA = new List<>();
List<ListenerB> ofListenersB = new List<>();
List<ListenerC> ofListenersC = new List<>();

void addListener(Listener listener) {
    if (listener instanceof ListenerA) {
        ofListenersA.add(listener);

        return;
    }

    if (listener instanceof ListenerB) {
        ofListenersB.add(listener);

        return;
    }

    if (listener instanceof ListenerB) {
        ofListenersB.add(listener);

        return;
    }
}

void removeListener(Listener listener) {
    if (listener instanceof ListenerA) {
        ofListenersA.remove(listener);

        return;
    }

    if (listener instanceof ListenerB) {
        ofListenersB.remove(listener);

        return;
    }

    if (listener instanceof ListenerB) {
        ofListenersB.remove(listener);

        return;
    }
}

但现在我必须单独评估每个 instanceof,因为你不能在一个类上 switch

这不是要求优化的尝试,因为我没有多种类型的监听器可供检查;而是一个问题,即在面向对象设计方面,这是否是一种糟糕的方法。

更新

在接口(interface)中使用枚举的短路方法:

enum ListenerType {
    ListenerTypeA,
    ListenerTypeB,
    ListenerTypeC
}

public interface Listener {
    ListenerType getType();
}

public class ListenerA extends Listener {
    ListenerType getType() {
        return ListenerType.ListenerTypeA;
    }
}

public class ListenerB extends Listener {
    ListenerType getType() {
        return ListenerType.ListenerTypeB;
    }
}

public class ListenerC extends Listener {
    ListenerType getType() {
        return ListenerType.ListenerTypeC;
    }
}

List<ListenerA> ofListenersA = new List<>();
List<ListenerB> ofListenersB = new List<>();
List<ListenerC> ofListenersC = new List<>();

void addListener(Listener listener) {
    switch (listener) {
        case ListenerTypeA: {
            ofListenersA.add(listener);

            return;
        }
        case ListenerTypeB: {
            ofListenersB.add(listener);

            return;
        }
        case ListenerTypeC: {
            ofListenersC.add(listener);

            return;
        }
    }
}

void removeListener(Listener listener) {
    switch (listener) {
        case ListenerTypeA: {
            ofListenersA.remove(listener);

            return;
        }
        case ListenerTypeB: {
            ofListenersB.remove(listener);

            return;
        }
        case ListenerTypeC: {
            ofListenersC.remove(listener);

            return;
        }
    }
}

最佳答案

我建议您添加一个类型来指定您感兴趣的监听器类型。您也可以将键更改为其他内容,例如带有 hashCode 和 equals 的常规类。

enum ListenerType {
    TYPE_A, TYPE_B, TYPE_C
}

interface Listener {

}

Map<ListenerType, Set<Listener>> listeners = new ConcurrentHashMap<>();

public void addListener(ListenerType type, Listener listener) {
    listeners.computeIfAbsent(type, k -> Collections.newSetFromMap(new ConcurrentHashMap<>())).add(listener);
}

public void removeListener(ListenerType type, Listener listener) {
    listeners.computeIfPresent(type, (k, v) -> v.remove(listener) && v.isEmpty() ? null : v);
}

public Set<Listener> getListeners(ListenerType type) {
    return listeners.getOrDefault(type, Collections.emptySet());
}

关于java - 有没有更好的方法来短路 instanceof 链?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42037437/

相关文章:

java - 如何在有可用空间(如密度扫描仪)的 pdf 上插入图像或图章

java - 我正在使用 .getRGB() 和 .setRGB() 来获取 BufferedImage 的一部分,如何复制透明度?

c++ - 我必须实例化这个类吗?或者这是一种糟糕的职责分离?

android - 如何压缩重复的 switch 语句

java - 在个人 java oss 项目中包含高度定制的 java oss 的正确方法?

java - 有没有办法触发 Maven Appengine Devserver 自动刷新静态文件?

performance - 什么对性能更好,对象元胞数组还是异构数组?

c++ - 指向基址,转换为派生指针

c - 一条 switch 语句占用多少代码空间?

c++ - C++自动生成switch语句