And when I talk about indentation, I mean nested if statements, another one of my pet peeves.
This specific refactoring is called: Replace Nested Conditional with Guard Clauses[1].
Preconditions (GuardClauses) are a great example of where it is okay to return early at the start of the function.
It is very convenient to prevent the ArrowAntiPattern.
Here a bad example:
public boolean getPayment(String a, Double b)
{
boolean result = false;
if (a != null && b != null && !a.equals("") && b >= 0.0)
{
User user = getUser(a);
if (user != null && user.getAccountValue() >= b))
{
user.setAccountValue(user.getAccountValue() - b);
return true;
}
else
{
log.debug("User account not found or insufficient funds.");
result = false;
}
}
else
{
log.debug("Bad values.");
result = false;
}
return result;
}
{
boolean result = false;
if (a != null && b != null && !a.equals("") && b >= 0.0)
{
User user = getUser(a);
if (user != null && user.getAccountValue() >= b))
{
user.setAccountValue(user.getAccountValue() - b);
return true;
}
else
{
log.debug("User account not found or insufficient funds.");
result = false;
}
}
else
{
log.debug("Bad values.");
result = false;
}
return result;
}
Here a good example (bad example refactored):
public boolean getPayment(String a, Double b)
{
// preconditions
if (a == null || b == null)
{
log.debug("Null values");
return false;
}
if ("".equals(a) || b <= 0.0)
{
log.debug("Bad values");
return false;
}
User user = getUser(a);
if (user == null)
{
log.debug("User account not found.");
return false;
}
if (user.getAccountValue() < b)
{
log.debug("Insufficient funds.");
return false;
}
user.setAccountValue(user.getAccountValue() - b);
return true;
}
{
// preconditions
if (a == null || b == null)
{
log.debug("Null values");
return false;
}
if ("".equals(a) || b <= 0.0)
{
log.debug("Bad values");
return false;
}
User user = getUser(a);
if (user == null)
{
log.debug("User account not found.");
return false;
}
if (user.getAccountValue() < b)
{
log.debug("Insufficient funds.");
return false;
}
user.setAccountValue(user.getAccountValue() - b);
return true;
}
One important skill here is the proper negation of an expression. You'd be surprised how many people lack this skill.
References
- [1] Refactoring - Improving the design of existing code
- Martin Fowler
No comments:
Post a Comment