java - 在此用例中使用反射来解决我不允许修复的设计问题是否合理?

标签 java xml inheritance reflection xml-binding

以下用例是否被认为有理由进行反射(reflection)?

有一堆从 XSD 生成的类(目前项目中有数百个)代表各种响应。

所有这些响应都包含通用响应数据结构,而不是对其进行扩展。

当超时等事件发生时,我只需要将单个字符串设置为特定值。

如果这些类扩展了公共(public)响应结构,我总是可以设置此响应代码而无需反射,但事实并非如此。

因此我为我的服务编写了简单的实用程序,它使用反射来获取 String 字段的 setter 方法并使用预定义的值调用它。 我唯一知道的替代方法是使用特定于类的方法,这些方法会复制代码来处理超时,唯一的区别是返回的 Response 类。

protected T handleTimeout(Class<T> timeoutClass) {
    try {
        T timeout = timeoutClass.newInstance();
        Method setCode = timeoutClass.getDeclaredMethod(SET_RESPONSE_CODE, String.class);
        setCode.invoke(timeout, Response.TIMEOUT.getCode());
        return timeout;
    } catch (InstantiationException | IllegalAccessException  | SecurityException | NoSuchMethodException | IllegalArgumentException | InvocationTargetException e) {
        e.printStackTrace();
        throw new RuntimeException("Response classes must have field: \"code\" !");
    }

}

相关事实:

  • 此 setter 方法永远不应更改,因为它需要重新编写数百个接口(interface)

有人可以指出我是否遗漏了一些陷阱,或者是否有替代的反射解决方案可以达到相同的结果?

编辑:我无权对 XSD 进行任何更改,因此任何解决方案都必须在本地完成。序列化此类对象应该没有问题,因为它们在组件之间共享。

最佳答案

首先,@kutschkem 建议有一个标准的、正常的日常解决方案,特别是:声明一个只包含这个 setter 方法的接口(interface),并在每个需要它的类中实现该接口(interface)。这使用标准多态性来完全满足您的需求。

我知道这需要更改很多类的定义(但更改是微不足道的 - 只需将“implements MytimeoutThing”添加到每个类) - 即使对于 1000 个类,这对我来说似乎也是一个相当容易的修复。

我认为反射确实存在问题:

  1. 您正在为所有必须支持的类创建一个 secret 接口(interface),但该接口(interface)没有契约(Contract) - 当新开发人员想要添加一个新类时,他必须神奇地知道名称和签名这个方法——如果他弄错了,代码就会在运行时失败,因为编译器不知道这个契约。 (因此,像拼错 setter 名称这样简单的事情不会被编译器识别)

  2. 它很丑陋,隐藏起来并且不属于软件的任何特定部分。维护这些类中的任何一个的开发人员会发现这个函数(setter)注意到它永远不会被调用并且只是删除它 - 毕竟项目其余部分中没有代码引用该 setter 所以它显然不需要。

  3. 很多静态分析工具都无法工作 - 例如,在大多数 IDE 中,您可以建立调用特定函数的所有位置以及调用特定函数的所有位置 - 显然是这种功能如果您使用反射则不可用。在一个有数百个几乎相同类的项目中,我不想失去这个设施。

关于java - 在此用例中使用反射来解决我不允许修复的设计问题是否合理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30595218/

相关文章:

java - Java是“按引用传递”还是“按值传递”?

java - 在嵌入式 Neo4j 中设置 keep_logic_logs

c++ - 从 SAX 解析器事件填充 C++ POD 结构

php - 使用 PHP 和 Ajax 将 XML 数据插入 Mysql 表

Python 2.7 : inheritance with OrderedDict Attribute error <myclass> class has no attribute '_OrderedDict__root'

java - 正确的 java.util.ResourceBundle 组织

java - Bigquery Java API 以 BigDecimal 形式返回计费层级

java - 如何配置pom文件和TeamCity在maven java项目中构建依赖模块?

c# - 从仅在方法中设置类型的接口(interface)获取具有泛型类型的对象

java - 为什么 Comparable 在 jdk 1.8 中没有声明为 @FunctionalInterface 尽管它是 FunctionalInterface 之一?