微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

良好的设计,如果对象映射

如何解决良好的设计,如果对象映射

我有这个逻辑:

public void method(Boo result,Foo foo,Bar bar) {
   if(foo != null) {
      if(foo.getId() != null){
         result.setId(foo.getId());
      } else {
         result.setId(bar.getId());
      }
      if(foo.getName() != null){
         boo.setName(foo.getName());
      } else {
         result.setName(bar.getName());
      }
      // and many similar attributes
   } else {
      result.setId(bar.getId());
      result.setName(bar.getName());
      // and many similar attributes
   }
}

我发现这种方式很难看,有没有办法使它更好的设计。我知道使用mapstruct更好,但是在这个项目中我做不到。

解决方法

我会切换测试。它稍微干净一点,但看起来仍然很凌乱。

public void method(Boo result,Foo foo,Bar bar) {
    setResult(result,bar);
    if (foo != null) { setResult(result,foo); }
}

private void setResult(Boo result,Bar bar) {
    result.setId(bar.getId());
    ...
}

private void setResult(Boo result,Foo foo) {
    if (foo.getId != null) { result.setId(foo.getId()); }
    ...
} 
,

我避免使用ObjectUtils::firstNonNull作为吼叫:

public void method(Boo result,Bar bar) {
   if(foo != null) {
      result.setId(ObjectUtils.firstNonNull(foo.getId(),bar.getId()));
      result.setId(ObjectUtils.firstNonNull(foo.getName(),bar.getName()));
      // and many similar attributes
   } else {
      result.setId(bar.getId());
      result.setName(bar.getName());
      // and many similar attributes
   }
}

我愿意接受其他建议!

,

通过将foo作为Optional,您可以像这样简化代码:

Optional<Foo> optionalFoo = Optional.ofNullable(foo);
    
result.setId(optionalFoo.map(Foo::getId).orElseGet(bar::getId));
result.setName(optionalFoo.map(Foo::getName).orElseGet(bar::getName));
// ...
,

具有通用的类/界面:

如果NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7" Foo扩展了公共基类/接口,则可以创建一个通用方法来将逻辑应用于任何属性。

例如,假设他们实现了此接口:

Bar

然后我们可以创建此通用方法:

public interface IBaseInterface {
    Long getId();
    String getName();
}

并像这样使用它:

public static <T> T getAttribute(IBaseInterface foo,IBaseInterface bar,Function<IBaseInterface,T> function) {
    if(foo != null) {
        T attribute = function.apply(foo);
        if(attribute != null) {
            return attribute;
        }
    }
    return function.apply(bar);
}

没有通用的类/界面:

如果它们不扩展通用的基类/接口,您仍然可以使用此技术,但必须将另一个参数传递给方法:

result.setId(getAttribute(foo,bar,IBaseInterface::getId));
result.setName(getAttribute(foo,IBaseInterface::getName));

并像这样使用它:

public static <T> T getAttribute(Foo foo,Bar bar,Function<Foo,T> functionFoo,Function<Bar,T> functionBar) {
    if(foo != null) {
        T attribute = functionFoo.apply(foo);
        if(attribute != null) {
            return attribute;
        }
    }
    return functionBar.apply(bar);
}
, 如果随后只有一个语句,则

if语句不需要大括号{}。可以将它视为{...},并将其包装在其中的其他语句中。
而且Java并不真正关心空格和缩进,因此您可以将多个语句放在同一行中。

有了这些知识,您可以使代码更漂亮:

public void method(Boo result,Bar bar) {
    if (foo != null) {
        if (foo.getId() != null) result.setId(foo.getId());
        else result.setId(bar.getId());

        if (foo.getName() != null) boo.setName(foo.getName());
        else result.setName(bar.getName());

    } else {
        result.setId(bar.getId());
        result.setName(bar.getName());
   }
}

或至少删除{}

public void method(Boo result,Bar bar) {
    if (foo != null) {
        if (foo.getId() != null)
            result.setId(foo.getId());
        else 
            result.setId(bar.getId());

        if (foo.getName() != null)
            boo.setName(foo.getName());
        else 
            esult.setName(bar.getName());

    } else {
        result.setId(bar.getId());
        result.setName(bar.getName());
   }
}
,

如果映射对象具有相同的属性,并且项目依赖项中包含spring bean,则BeanUtils.copyProperties(source,destination);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。