Coding Practice: Which has higher cyclomatic complexity, a one line LINQ query or 20 lines of code?
Well, it depends. Take the single line of code below as an example:
List<RecipesWithDetail> recipesList = (from summaryRecipe in Data.summaryRecipees from detail in summaryRecipe.RecipeDetails where detail.IsPublished && (detail.Type == _InCookbook || detail.Type == _InBlog) select new RecipesWithDetail { RecipeNumber = detail.RecipeNumber, RecipeDate = detail.RecipeDate, StepNumber = summaryRecipe.StepNumber, StepDetail = summaryRecipe.StepDetail }).ToList<RecipesWithDetail>();
This one line LINQ query has a cyclomatic complexity of 11. Keep in mind that any score higher than 10 is considered an indicator that your code might need to be refactored, so that is a pretty high score for a whole method let alone a single line of code.
Quote:
“There are many good reasons to limit cyclomatic complexity. Overly complex modules are more prone to error, are harder to understand, are harder to test, and are harder to modify.”
– Thomas McCabe
Application:
If you take the above LINQ query and convert it to a pure code statement, you would get the equivalent of 2 foreach statements and 4 lambda expressions. Indeed, that single line of code is representing an entire method’s worth of functionality. I would recommend just formatting the code so it is more readable and don’t try to add much more functionality to the method that holds this code.
Example reformatting:
var summaryRecipeResults = from summaryRecipe in Data.summaryRecipees from detail in summaryRecipe.RecipeDetails where detail.IsPublished && (detail.Type == _InCookbook || detail.Type == _InBlog) select new RecipesWithDetail { RecipeNumber = detail.RecipeNumber, RecipeDate = detail.RecipeDate, StepNumber = summaryRecipe.StepNumber, StepDetail = summaryRecipe.StepDetail }; var recipesList = summaryRecipeResults.ToList<RecipesWithDetail>();
There are a couple of takeaways from the above single line of code:
1) Readability should be favored over trying to reach some sort of artificial maximum limit on the number of lines of code in a method.
2) LINQ can be used to produce highly readable code, but be aware that LINQ is simplifying a tremendous amount of power. As such, you should try to optimize your queries and write your code in such a way that you minimize the amount of LINQ that is required to do the job.
References:
http://hissa.nist.gov/HHRFdata/Artifacts/ITLdoc/235/title.htm