3 ms·
My personal rules of thumb are: 1. Keep the business logic as un-indented as possible. 2. If there are several branching happy-paths, give them the same inden
by stopping 6y ago
My personal rules of thumb are:
1. Keep the business logic as un-indented as possible.
2. If there are several branching happy-paths, give them the same indentation.
I generally choose the "early return" pattern if there is (1) more than one precondition that must be met before executing a (2) medium-sized "happy path" code body. In these situations, having the meat of your function inside a deeply nested flow control structure is unwieldy, and for indentation-sensitive languages it is far too easy to lose track of which condition body you're currently in. In Python, this has bitten me more times than I can count.
So, my standard "early return" pattern follows this prototype:
if (!discriminatingPrecondition) {
// Some cases we ignore intentionally.
return false;
}
if (!criticalPrecondition) {
std::err << "Error: Precondition not met!" << std::endl;
return false;
}
if (!fixablePrecondition) {
scheduleRemedyForPrecondition();
return false;
}
// Happy path
return true;
However, for code with a single precondition statement without specific remediation logic for each precondition, I might occasionally prefer:
if (preConditionA && preConditionB && preConditionC) {
// happy path
} else {
std::err << "Error: Preconditions not met!" << std::endl;
}
In the above examples, single entry/exit forces a structure like this:
if (preConditionA) {
if (preConditionB) {
if (preConditionC) {
// happy path
...
...
...
} else {
std::err << "User not authenticated!";
}
} else {
std::err << "No server connection!";
scheduleServerConnection();
}
} else {
std::err << "No network connection!";
scheduleConnectionCheck();
}
Now, outside of "precondition" checking, it makes sense to use if/else or switch statements when conditions lead to similar happy path bodies. For example:
if (shouldStand) {
stand();
} else {
// No implied difference of statement body importance based on indentation
sit();
}
Versus:
if (shouldStand) {
stand();
return;
}
// Hmm, is this path significantly different from the one above?
sit();
So, in the "branching happy path" situation I opt for the former.