Reputation: 171
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.
Upvotes: 0
Views: 666
Reputation: 7638
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));
Upvotes: 1
Reputation: 7638
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));
// ...
Upvotes: 1
Reputation: 171
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!
Upvotes: 1
Reputation: 152
If the mapping objects are having same properties, and if you have spring beans in your project dependency, BeanUtils.copyProperties(source, destination);
Upvotes: 0
Reputation: 517
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.
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());
}
}
Upvotes: 0
Reputation: 51565
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()); }
...
}
Upvotes: 2