Inverted If
Most developers think in terms of nested logic. It's difficult for them to invert their logic to reduce nesting. Deeply nested code is more difficult to read, and to reduce nesting you often have to invert your logic.
When a programmer writes code they write in a logical tree structure like this.
bool function publish(Document doc)
{
if(doc != null)
{
if(doc.status == "finished")
{
doc.print();
if(doc.locked)
{
doc.unlock();
}
return true;
}
return false;
}
return false;
}
The above is logically correct, but it introduces indents that make it difficult to maintain in the future. It's difficult, because additional logic will require deeper blocks. The deeper it gets the more likely a bug will be introduced.
By inverting your if statements and combining them you can reduce the nesting.
bool function publish(Document doc)
{
if(doc == null || doc.status != "finished")
{
return false
}
doc.print();
if(!doc.locked)
{
return true;
}
doc.unlock();
return true;
}
This inverted kind of logic keeps all the function operations within the first indented block and if statements are only used to terminate the function.
Split Loop And Work
Don't perform your work operations inside a loop block. Separate iteration from the task itself. This creates functions of single purpose.
Take this example
function void PrintDocuments(List<Document> pDocuments)
{
for(int doc=0; doc < pDocuments.Count; doc++)
{
for(int page=0; page < pDocuments[doc].Pages.Count; page++)
{
pDocuments[doc].Pages[page].Print();
}
}
}
While that isn't very complex it does create 3 levels of nesting, and the function is performing three different tasks.
Split the work and loops makes it easier to maintain.
function void PrintDocuments(List<Document> pDocuments)
{
for(int doc=0; doc < pDocuments.Count; doc++)
{
PrintPages(pDocuments[doc].Pages);
}
}
private function void PrintPages(Document pDocument)
{
for(int page=0; page < pDocument.Pages.Count; page++)
{
PrintPage(Pages[page]);
}
}
private function void PrintPage(Page pPage)
{
pPage.Print();
}
One could argue that the above is extra work, but the time spend to split the tasks and create functions of single purpose will reduce effort later when maintaining the code. The reduced indention makes it easier to read. The work to be completed by a loop is never performed inside a loop, but is handled by a dedicated function for that work PrintPage
.
Conclusion
Single purpose and inverted logic are the keys to reducing indentations.
break
andcontinue
to lessen some indentation