有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用instanceof替代ifelse的json Java设计

我们的Java应用程序在后端使用Google Guava EventBus进行通信。其中一些事件通过Jersey的server-sent eventssupport发送到客户端以启用通知。客户端只对某些类型的事件感兴趣,这些事件以JSON格式发送到客户端

目前,我们正在使用if-elseinstanceof以一种巨大的方法处理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的一个很好的替代品,但在这种情况下确实有效。使用多态性意味着向UIEvent接口添加类似toJSON的方法。但这会还原依赖项流,并向事件总线公开UI细节

3)包装类

我还考虑使用事件包装器类将JSON body building逻辑封装在单独的类中。然后在事件总线的handleEvent方法中,我可以获取事件对象的类型,并使用命名约定找到包装类,然后构造包装类实例,调用toJson方法来获取JSON主体

public class AWrapper {
   public AWrapper(A a) {

   }

   public Object toJson() {

   }
}

这是迄今为止我能想到的最合理的方法

需要建议和想法


共 (1) 个答案

  1. # 1 楼答案

    我相信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!

    通过创建自己的标记,你正在创建他们试图避免的问题

    对我来说,番石榴建议这样使用它:

    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/