英文:
Good Design for if else object mapping
问题
我有这个逻辑:
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());
}
// 以及许多类似的属性
} else {
result.setId(bar.getId());
result.setName(bar.getName());
// 以及许多类似的属性
}
}
我发现这种方式很丑陋,是否有办法进行更好的设计?我知道使用MapStruct会更好,但在这个项目中我不能使用。
英文:
I have this logic:
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
}
}
I find this way ugly, is there any way to make it in better design. I know that is better to use mapstruct, but in this project I can't.
答案1
得分: 2
我会调整测试顺序。 这样会更清晰一些,但仍然会显得混乱。
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()); }
...
}
英文:
I'd switch the tests around. It's a little cleaner, but it's still going to look messy.
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()); }
...
}
答案2
得分: 1
我使用ObjectUtils::firstNonNull
来避免使用if else,代码如下:
public void method(Boo result, Foo foo, Bar bar) {
if(foo != null) {
result.setId(ObjectUtils.firstNonNull(foo.getId(), bar.getId()));
result.setId(ObjectUtils.firstNonNull(foo.getName(), bar.getName()));
// 以及许多类似的属性
} else {
result.setId(bar.getId());
result.setName(bar.getName());
// 以及许多类似的属性
}
}
我欢迎其他建议!
英文:
I avoid the if else using ObjectUtils::firstNonNull
as bellow:
public void method(Boo result, Foo foo, 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
}
}
I'm open for other suggests!
答案3
得分: 1
通过将 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));
// ...
英文:
By having foo
as an Optional
you could simplify your code like this:
Optional<Foo> optionalFoo = Optional.ofNullable(foo);
result.setId(optionalFoo.map(Foo::getId).orElseGet(bar::getId));
result.setName(optionalFoo.map(Foo::getName).orElseGet(bar::getName));
// ...
答案4
得分: 1
使用通用类/接口:
如果 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, bar, 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);
}
并像这样使用它:
result.setId(getAttribute(foo, bar, Foo::getId, Bar::getId));
result.setName(getAttribute(foo, bar, Foo::getName, Bar::getName));
英文:
With common class/interface:
If Foo
and Bar
extend a common base class/interface you could create a generic method to apply the logic to any attribute.
For example lets say that they implement this interface:
public interface IBaseInterface {
Long getId();
String getName();
}
Then we could create this generic method:
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);
}
And use it like this:
result.setId(getAttribute(foo, bar, IBaseInterface::getId));
result.setName(getAttribute(foo, bar, IBaseInterface::getName));
Without common class/interface:
If they don't extend a common base class/interface you could still use this technique but you'd have to pass another parameter to the method:
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);
}
And use it like this:
result.setId(getAttribute(foo, bar, Foo::getId, Bar::getId));
result.setName(getAttribute(foo, bar, Foo::getName, Bar::getName));
答案5
得分: 0
if
语句后面只有一个语句时,不需要使用花括号{}
。可以将{...}
视为包裹着许多其他语句的单个语句。
此外,Java并不会在意空格和缩进,因此您可以将多个语句放在同一行。
有了这个知识,您可以让代码看起来更漂亮,就像这样:
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());
} else {
result.setId(bar.getId());
result.setName(bar.getName());
}
}
或者至少去掉花括号{}
:
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
esult.setName(bar.getName());
} else {
result.setId(bar.getId());
result.setName(bar.getName());
}
}
英文:
if
statements don't need curly brackets {}
when there there is a single statement afterwards. Think of it as {...}
as a single statement wrapping many other inside it.
<br>Also Java doesn't really care about whitespaces and indentation so you can put multiple statements in the same line.
With this knowledge you can make the code prettier like this:
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());
} else {
result.setId(bar.getId());
result.setName(bar.getName());
}
}
or at the very least remove the {}
:
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
esult.setName(bar.getName());
} else {
result.setId(bar.getId());
result.setName(bar.getName());
}
}
答案6
得分: 0
如果映射对象具有相同的属性,并且项目依赖中有Spring Bean,可以使用BeanUtils.copyProperties(source, destination)。
英文:
If the mapping objects are having same properties, and if you have spring beans in your project dependency, BeanUtils.copyProperties(source, destination);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论