如何解决良好的设计,如果对象映射
我有这个逻辑:
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 举报,一经查实,本站将立刻删除。