作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 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());
这种方法的一些注意事项包括
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/
我是一名优秀的程序员,十分优秀!