Java设计替代if-else和instanceof
作者:互联网
我们的Java应用程序在后端使用Google Guava EventBus进行通信.其中一些事件使用Jersey的server-sent events support发送到客户端以启用通知.客户端仅对某些类型的事件感兴趣,并且这些事件以JSON格式发送到客户端.
目前我们正在使用if-else和instanceof来处理巨型方法中的JSON体生成. UIEvent只是一个用作过滤器的标记接口.
@Subscribe
public void handleEvent(final UIEvent event) {
if (event instanceof A) {
A a = (A) event;
} else if (event instance B) {
B b = (B) event;
} ...
}
当越来越多的事件被添加到系统时,此代码开始变得混乱.经过一些研究,有一些替代方案,但还不够好.
1)思考.
使用反射意味着我们可以使用声明方式从事件对象中检索数据,而无需知道确切的类型.但是使用反射不是类型安全的,并且在处理嵌套路径时可能会很麻烦,例如: A.B.C.
2)多态性
多态性看起来是instanceof的一个很好的替代品,但在这种情况下确实有效.使用多态意味着将类似toJSON的方法添加到UIEvent接口.但这会恢复依赖关系流并将UI细节暴露给事件总线.
3)包装类
我也在考虑使用事件包装器类将JSON主体构建逻辑封装在不同的类中.然后在事件总线的handleEvent方法中,我可以获取事件对象的类型并使用命名约定查找包装类,然后构造包装器类实例,调用toJson方法来获取JSON主体.
public class AWrapper {
public AWrapper(A a) {
}
public Object toJson() {
}
}
这是迄今为止我能想到的最合理的方法.
需要建议和想法.
解决方法:
我相信Google Guava EventBus是精确设计的,所以你不必用许多if-else-if来定义这样的方法:
Some have proposed a generic Handler interface for EventBus
listeners. This runs into issues with Java’s use of type erasure, not
to mention problems in usability.…
Due to erasure, no single class can implement a generic interface more than once with different type parameters. This is a giant step backwards from traditional Java Events, where even if actionPerformed and keyPressed aren’t very meaningful names, at least you can implement both methods!
通过创建自己的标记,您将重新创建他们试图避免的问题.
对我来说,这就是Guava建议使用它的方式:
EventBus eventBus = new EventBus();
eventBus.register(new Object(){
@Subscribe
public void handleEvent(A a) {
System.out.println("a");
}
});
eventBus.register(new Object(){
@Subscribe
public void handleEvent(B b) {
System.out.println("b");
}
});
...
eventBus.post(new A());
eventBus.post(new B());
每种事件类型一个处理程序方法显然,订阅者不需要像这个例子那样处于匿名类中.
其他例子
http://tomaszdziurko.pl/2012/01/google-guava-eventbus-easy-elegant-publisher-subscriber-cases/
标签:json,java,instanceof,architecture,software-design 来源: https://codeday.me/bug/20190711/1429827.html