gpt4 book ai didi

java - 在 Java 中将 A 类(和所有子类)映射到 B 类的实例

转载 作者:行者123 更新时间:2023-12-03 20:26:16 24 4
gpt4 key购买 nike

在 Java 中实现策略模式时,存在将输入数据类型映射到特定算法实例的常见问题。

例如,我们可以创建一个 map :

map.put(Apple.class, new AppleHandler());
map.put(Orange.class, new OrangeHandler());

并在运行时为给定的数据类型解析正确的处理程序:

Apple a = new Apple();
map.get(a.getClass()).handle(a);

问题:有没有Map<Class<A>, B>在 Guava/Apache Commons 等库中实现此类映射,可以处理多态类型?

例如上面的映射会像那样工作(假设 GreenApple 扩展了 Apple):

  map.get(Apple.class) == map.get(GreenApple.class);

我知道我可以编写遍历层次结构的实现,但我问的是 OTS 解决方案。

最佳答案

最简单的解决方案是简单地为具有多个类的处理程序添加多个映射条目:

map.put(Apple.class, new AppleHandler());
map.put(GreenApple.class, map.get(Apple.class));
map.put(Orange.class, new OrangeHandler());

这种方法的一些注意事项包括

  1. 如果您有很多类,那么您的 map 可能会变得有些大。
  2. 如果外部源可以定义类型为 A 的新类并在运行时提供它们,那么您还需要一些注册它们的方法(例如,通过在初始化时扫描类路径,提供某种注册供外部代码使用的 API,或者如果请求的键不在 map 中,则添加对遍历层次结构的支持)。

但是,如果您可以控制源代码,那么您可以在编译时在类本身中进行此“映射”:

interface A {
B getHandler();
}

interface B {
}

class Apple implements A {
public B getHandler() {
return AppleHandler.INSTANCE;
}
}

class GreenApple extends Apple {
}

class Orange implements A {
public B getHandler() {
return OrangeHandler.INSTANCE;
}
}

现在您可以通过简单地调用 getHandler() 方法来获取类 A 的任何实例的处理程序。由于 getHandler() 是契约(Contract)的一部分,因此定义 A 新类的外部源也必须实现它。

如果您不能更改类型 A 的来源或不想更改(到 separate concerns 等),那么您可以引入一个新的类型包装 A 使用 decorator pattern 定义映射.

关于java - 在 Java 中将 A 类(和所有子类)映射到 B 类的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34653952/

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