从 switch 重构多个 case

Shi*_*rty 5 java

TestDTO testDTO = new TestDTO();
    
for (Object attribute : row.getAttributes()) {
    switch (attribute) {
    case "CATEGORY":
        testDTO.setCategory((String) attribute);
        break;
    case "DESCRIPTION":
        testDTO.setDescription((String) attribute);
        break;
    case "NOTE":
        testDTO.setNote((String) attribute);
        break;
    case "FEATURES":
        testDTO.setFeatures((String) attribute);
        break;
    case "INDICATOR":
        testDTO.setIndicator((String) attribute);
        break;
    case "LABEL":
        testDTO.setLabel((String) attribute);
        break;
    case "TYPE":
        testDTO.setType((String) attribute);
        break;
    default:

    }
}
Run Code Online (Sandbox Code Playgroud)

正如你在上面的代码中看到的,我们使用多个 case 来设置数据。代码工作正常。

有什么方法可以减少设置这些数据的多种情况。

在上面的代码中,问题是可维护性。因为假设如果我们有 30 个字段,那么我们需要为此放置 30 个案例。

有没有其他方法可以实现相同的目标?

m.a*_*icz 5

如果不重构,您将无法做任何真正有助于解决问题的事情。此外,您还需要为每个字段添加特定代码 - 这很明显

在抽象情况下,您可以做的是实现工厂策略模式,例如为每种类型的属性注册适当的处理程序 - 类似

Map<Object, BiConsumer<TestoDTO, Object>> handlers; // then you can add for example handlers.put("TYPE", (d, a) -> d.setType(a))
Run Code Online (Sandbox Code Playgroud)

只需迭代属性

row.getAttributes().forEach(a -> handlers.get(attribute).accept(dto, a)); // ofc you need to handle all situation like NPE, no key etc
Run Code Online (Sandbox Code Playgroud)

在映射对象的范围内,您可以使用一些现有的工具,如ObjectMapperModelMapper,因为这些工具很可能开箱用地解决您的问题

最后也是最不重要的 (:)) 解决方案是使用一些反射,将属性映射到字段名称,提取 setter ......不要这样做:) 它是肮脏的、不安全的、难以编写和理解的 - 会导致许多你会后悔的问题但因为这是一个选项,所以我提到了这一点