Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is it a good idea to avoid nested blocks in a function? (PHP) [closed]

Tags:

php

I installed a Netbeans 7.4 beta, and there's a new hint that says "Too many nested blocks in function declaration - it's good practice to introduce new function...".

I do try to avoid nested blocks within a function for better readability, but is there any other reason why this would be a better "idea," specifically for PHP, if that matters.

like image 636
musicliftsme Avatar asked Aug 15 '13 16:08

musicliftsme


2 Answers

The formal name for this is Cyclomatic Complexity.

This is a measure of how complex a function is, based on the number of 'decision points' in the function. The higher the number, the more complex the function.

Complexity is determined by the number of decision points in a method plus one for the method entry. The decision points are 'if', 'while', 'for', and 'case labels'. Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.

(taken from http://phpmd.org/rules/codesize.html)

The reason it is considered bad to have your complexity values too high is because it makes the function difficult to test.

In order to test a function to its full potential, you need to have a separate test for each possible code path. The number of code paths increases exponentially with every new decision point, which means that by the time you've got more than a handful of decisions in a single function, you start needing hundreds of tests in order to be sure you've covered the whole range of functionality it might perform.

Hundreds of tests for a single function is clearly too many, so the better option is to reduce the number of decision points per function by splitting it into several smaller functions with fewer decisions each.

You also need to make the functions discrete so that they don't rely on each other to run. This allows them to be tested in isolation from each other. (otherwise you still have the original problem of too many decisions in a single call)

You can then test each of those functions with only a handful of the number of tests you would have originally required.

The process of testing functions in isolation of each other is called Unit Testing. This is a very large topic in itself, but well worth researching if you want to know more about good software development practices.

Since you've tagged this question PHP, I will point you in the direction of a few tools that mgiht help you:

  • PHP Unit - this is the de-facto standard unit testing package for PHP.
  • PHPMD - "PHP Mess Detector"; a tool for analysing your code to look for things like excessive complexity.
  • pDepend - Another similar tool.

There are a bunch of other tools available, but that's probably enough to get started; get to know those ones first. You'll come across others naturally as you research the topic.

like image 141
Spudley Avatar answered Oct 12 '22 11:10

Spudley


Generally, functions/methods are well written if they do only one thing but do it well.

When a method starts to exhibit nesting beyond 1 or 2 levels that's a sure sign it's trying to do more than one thing at once.

When there's a lot of nesting and conditionals in a function, it also makes its logic more convoluted and difficult to follow, as well as more difficult to test robustly.

Finally, if there's functionality buried deep into a nest in another method you can't reuse it easily. You'll have to cut and paste it where you want to use it (which always leads to a maintenance nightmare) or add some additional switch and another conditional to the hosting method (which just exacerbates the issue). If you refactor that functionality out into its own method reusing it is trivial.

like image 41
GordonM Avatar answered Oct 12 '22 13:10

GordonM