Code Simplicity

And practical ways to reduce code complexity

Shai Boharon

Promise

  • Cyclomatic code complexity metric

  • practical and simple ways to reduce code complexity

What is code Simplicity?

The opposite of code complexity

Cyclomatic code complexity

Start

For

Some code

Is divided by 7

End

Boom

Has

the digit 7

For end

using System;

class Program
{
    static void Main()
    {
        SevenBoom(100);
    }

    static void SevenBoom(int limit)
    {
        for (int num = 0; num <= limit; num++)
        {
            bool itDividesBySeven = num % 7 == 0;
            bool hasSevenDigit = num.ToString().Contains("7");

            if (itDividesBySeven || hasSevenDigit)
            {
                Console.WriteLine($"Boom: {num}");
            }
        }
    }
}

Calculate code complexity

Start

For

Some code

Is divided by 7

End

Boom

Has

the digit 7

For end

using System;

class Program
{
    static void Main()
    {
        SevenBoom(100);
    }

    static void SevenBoom(int limit)
    {
        for (int num = 0; num <= limit; num++)
        {
            bool itDividesBySeven = num % 7 == 0;
            bool hasSevenDigit = num.ToString().Contains("7");

            if (itDividesBySeven || hasSevenDigit)
            {
                Console.WriteLine($"Boom: {num}");
            }
        }
    }
}

Calculate code complexity

1

2

3

4

Indication in the code

If statement if(some_condition) { … }

Case statement case any_value:

While statement while(some_condition) { ... }

For statement for, foreach,  for of

Catch statement catch(ExceptionType error) { .. }

Boolean operators  &&, ||

Ternary operator some_condition ? one_value : other_value

Null check operator some_object?.some_property?.sub_property

Elvis operator variable = some_value ?? other_value

How to achieve simplicity

  • Awareness
  • Code design
  • Automatic tools

Code design

  • Preferring default values over null and optional fields
  • Boolean algebraic
  • Preferring functional programming like LINQ over for loops
  • Preferring minimal try-catch
  • Encapsulation of complexity
  • Polymorphism
  • Recognizing the need of Factory, Strategy and Command design pattern
  • Null object pattern
  • Maybe (Option) and Either functors

Anemic domain model anti-pattern

public interface ISegmentGroup
{
    string Id { get; set; }
    string Name { get; set; }
    string Provider { get; set; }
    int? Size { get; set; }
    decimal? Cost { get; set; }
}

public class SegmentUtilities
{
    public static string GetSegmentName(ISegmentGroup segment)
    {
        if (!string.IsNullOrEmpty(segment.Name) && !string.IsNullOrEmpty(segment.Provider))
        {
            return segment.Name + segment.Provider;
        }
        return null;
    }

    public static decimal GetSegmentCost(ISegmentGroup segment)
    {
        return (segment.Size ?? 0) * (segment.Cost ?? 0);
    }
}

Default values and Null object pattern

public interface ISegmentGroup
{
    string Id { get; set; }
    string Name { get; set; }
    string Provider { get; set; }
    int Size { get; set; }
    decimal Cost { get; set; }
}

public class SegmentGroup : ISegmentGroup
{
    public string Id { get; set; } = ""
    public string Name { get; set; } = ""
    public string Provider { get; set; } = ""
    public int Size { get; set; }
    public decimal Cost { get; set; }

    public bool IsEmpty()
    {
        return String.IsNullOrEmpty(Id);
    }

    public string GetSegmentName()
    {
        return Name + Provider;
    }

    public decimal GetSegmentCost()
    {
        return Size * Cost;
    }
}

Tools

  • Visual Studio Code Metrics

    • ​​​​​​​Analyze -> Calculate Code Metrics -> for Solution

  • ReSharper

    • simplifying boolean operators

    • Inspector find "Method is too complex" or "Method has too many parameters"

    • refactoring to use LINQ

  • SonarQube

  • NDepend

summary

  • Cyclomatic complexity metric
  • Design solutions
  • Automatic tools

Thanks

Made with Slides.com