Ale*_*eng 5 java architecture json software-design instanceof
我们的 Java 应用程序在后端使用Google Guava EventBus进行通信。其中一些事件使用 Jersey 的服务器发送事件 支持发送到客户端以启用通知。客户端仅对某些类型的事件感兴趣,并且这些事件以 JSON 格式发送到客户端。
目前,我们正在使用if-elsewithinstanceof来处理巨型方法中的 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;
} ...
}
Run Code Online (Sandbox Code Playgroud)
当越来越多的事件添加到系统中时,这段代码开始变得混乱。经过一番研究,有一些替代方案,但还不够好。
1)反思。
使用反射意味着我们可以使用声明性方式从事件对象中检索数据,而无需知道确切的类型。但是使用反射不是类型安全的,并且在处理嵌套路径时可能会很混乱,例如a.b.c.
2)多态性
多态性看起来是一个很好的替代方案instanceof,但在这种情况下确实有效。使用多态性意味着toJSON向UIEvent接口添加类似的方法。但这会恢复依赖流并将 UI 详细信息暴露给事件总线。
3)包装类
我还在考虑使用事件包装器类将 JSON 主体构建逻辑封装在单独的类中。然后在事件总线的handleEvent方法中,我可以获取事件对象的类型并使用命名约定找到包装类,然后构造包装类实例,调用toJson方法来获取 JSON 主体。
public class AWrapper {
public AWrapper(A a) {
}
public Object toJson() {
}
}
Run Code Online (Sandbox Code Playgroud)
这是迄今为止我能想到的最合理的做法。
需要建议和想法。
我相信Google Guava EventBus是经过精确设计的,因此您不必使用许多 if-else-if 来定义此类方法:
有些人提出了一个用于 EventBus 监听器的通用 Handler 接口。这会遇到 Java 使用类型擦除的问题,更不用说可用性问题了。
...
由于擦除,任何单个类都不能使用不同的类型参数多次实现通用接口。这与传统的 Java 事件相比是一个巨大的倒退,即使 actionPerformed 和 keyPressed 不是非常有意义的名称,至少您可以实现这两种方法!
通过创建自己的标记,您正在重新创建他们试图避免的问题。
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());
Run Code Online (Sandbox Code Playgroud)
每种事件类型一个处理程序方法。显然,订阅者不需要像本示例中那样处于匿名类中。
http://tomaszdziurko.pl/2012/01/google-guava-eventbus-easy-elegant-publisher-subscriber-cases/
| 归档时间: |
|
| 查看次数: |
954 次 |
| 最近记录: |