We have a fair amount of code which looks like this:
private boolean isThingChanged(String newName, Thing thing) {
final Part part = thing.getPart();
if (part == null && newName == null) {
return false;
}
if (part == null || newName == null) {
return true;
}
return !part.getName().equals(newName);
}
That is, if the thing's current part is null and we're trying to set its name to null, that's not a change. If the part is null or the name is null, but not both, that is a change. And if neither is null, we have to look at it a little closer.
Thing and Part represent different entities for different such methods, so the first and final lines have the same general form but different specifics.
As written, this generates a SimplifiableIfStatement warning in Intellij, which would prefer to see it as:
private boolean isThingChanged(String newName, Thing thing) {
final Part part = thing.getPart();
return !(part == null && newName == null) && (part == null || newName == null || !part.getName().equals(newName));
}
Which is arguably simpler, but certainly not easier for me to read. I can of course suppress the warning with @SuppressWarnings("SimplifiableIfStatement")
but prefer to avoid that if possible.
I would like to find a way to extract this bit:
if (part == null && newName == null) {
return false;
}
if (part == null || newName == null) {
return true;
}
which is duplicated in all the instances of this code, because (a) it triggers the SimplifiableIfStatement warning and (b) it just seems too wordy to have it everywhere. So far I've come up with this:
private Boolean changedFromNull(Object a, Object b) {
// if both are null, nothing has changed.
if (a == null && b == null) {
return false;
}
// if only one is null, something has changed
if (a == null || b == null) {
return true;
}
// if neither is null, further analysis is required
return null;
}
but that's arguably even worse, because now the calling code has to null-check the result of this method in addition to all the other null checking already going on.
private boolean isThingChanged(String newName, Thing thing) {
final Part part = thing.getPart();
final Boolean changedFromNull = changedFromNull(part, newName);
return changedFromNull != null ? changedFromNull : !part.getName().equals(newName);
}
What's a good approach to this?