Category Archives: Design Patterns

Cyclomatic Complexity – What it is, why you should care, and how to reduce it using the Strategy Pattern

Cyclomatic complexity is one of those terms that makes you think you missed something when you were learning programming. However, the concept is a really simple one. Cyclomatic complexity is simply the number of paths through your code. There are more detailed explanations if you scan the web (involving edges and nodes), but for this post, we’ll just work with that.

Code Metrics

This article is not about .Net per se – what I’m writing here applies to any OO language; however, for the purpose of illustration, I’ll be using C#, and the Code Metrics Window in Visual Studio.

Cyclomatic Complexity

Given what we’ve just said, we can take the following program:

int x = 1;

And we can determine that the cyclomatic complexity is 1 – that is, there is only one way that this code can execute – no branches, no loops, just one statement. So, the cyclomatic complexity is 1:

Okay, let’s now add a single branch:

There are now two ways this code can execute (in actuality, there is only one, but cyclomatic complexity doesn’t follow the actual logical course – so let’s agree on two for the sake of argument).

We can now add a second condition:

The complexity now goes to three.

Okay, so that’s all very interesting, but what does that actually mean – why is it useful to know this number? The main answer to this is testability: if you know there are 3 possible execution paths for the code, then you know that you need a minimum of 3 tests to cover those paths. There’s a second part to that, which is that a method that requires one – three tests might be easy to change or debug, one that requires ten – twenty tests is definitely not.

So, the question is, how can we reduce this figure?

Reducing Cyclomatic Complexity

There are, obviously, more answers to this than would fit in this post, but here I’m going to focus on bringing in a strategy pattern.

Let’s consider the following code:

    // Night
    switch (thingToAutomate)
    {
        case "Door":
            Console.WriteLine("Lock");
            break;

        case "Window":
            Console.WriteLine("Close");
            break;

        case "TV":
            Console.WriteLine("Turn off");
            break;

        case "Lights":
            Console.WriteLine("Turn off");
            break;
    }

This method had a cyclomatic complexity of 5 – there are 4 options, but also the possibility that none are true.

The essence behind the strategy pattern is just that you assign functionality using polymorphism. If we consider the code above, doing that would actually increase the number of lines of code, and thereby increase the cyclomatic complexity. However, what if, in addition to the automation routine at night, we needed one for the morning:

// Morning
switch (thingToAutomate)
{
    case "Door":
        Console.WriteLine("Unlock");
        break;

    case "Window":
        Console.WriteLine("Open");
        break;

    case "TV":        
    case "Lights":        
        break;
}

Okay, now our cyclomatic complexity increases (to 9) – and will increase every time we need to vary our behaviour based on the thing that we’re automating. Instead, let’s consider the following:

    internal interface IThingToAutomateStrategy
    {
        void Morning();
        void Night();
    }

Let’s now imagine that we implement the interface for each thing:

    internal class Door : IThingToAutomateStrategy
    {
        public void Morning()
        {
            Console.WriteLine("Unlock");
        }

        public void Night()
        {
            Console.WriteLine("Lock");
        }
    }

    . . .

Admittedly, this does increase the lines of code, but we end up with simpler code, and it has a lower, overall, cyclomatic complexity:

    internal class Automation
    {
        public IThingToAutomateStrategy AutomateStrategy { get; set; }

        public void AutomateMorning()
        {
            AutomateStrategy.Morning();            
        }

        public void AutomateNight()
        {
            AutomateStrategy.Night();
        }
    }

We can then use this in our program like this:

IThingToAutomateStrategy automateStrategy;

switch (thingToAutomate)
{
    case "Door":
        automateStrategy = new Door();
        break;

    case "Window":
        automateStrategy = new Window();
        break;

    case "TV":
        automateStrategy = new TV();
        break;

    case "Lights":
        automateStrategy = new Lights();
        break;
}

automateStrategy.Morning();
automateStrategy.Night();

The cyclomatic complexity of this is back to 5; but the best part is that it doesn’t increase. Imagine the following new method:

    internal interface IThingToAutomateStrategy
    {
        void Morning();
        void Darkness();
        void Night();
    }

And the implementation:

    internal class Lights : IThingToAutomateStrategy
    {
        public void Darkness()
        {
            Console.WriteLine("Switch on");
        }

        public void Morning()
        {
            // Nothing to do here
        }

        public void Night()
        {
            Console.WriteLine("Turn Off");
        }
    }

It’s worth pointing out that we’re in breach of the ISP here – but since we’re only doing it to make a point, we’ll agree to let it slide.

Adding this to the code flow doesn’t affect the cyclomatic complexity score of that code file at all:

IThingToAutomateStrategy automateStrategy;

switch (thingToAutomate)
{
    case "Door":
        automateStrategy = new Door();
        break;

    case "Window":
        automateStrategy = new Window();
        break;

    case "TV":
        automateStrategy = new TV();
        break;

    case "Lights":
        automateStrategy = new Lights();
        break;
}

automateStrategy.Morning();
automateStrategy.Darkness();
automateStrategy.Night();

It’s worth noting that it does increase the overall complexity, as it counts as a single additional code path per thing.

References

https://docs.microsoft.com/en-us/visualstudio/code-quality/code-metrics-cyclomatic-complexity?WT.mc_id=DT-MVP-5004601

https://docs.microsoft.com/en-us/visualstudio/code-quality/how-to-generate-code-metrics-data?WT.mc_id=DT-MVP-5004601

https://codinghelmet.com/articles/reduce-cyclomatic-complexity-composite-design-pattern

https://www.c-sharpcorner.com/UploadFile/shinuraj587/strategy-pattern-in-net/

https://codewithshadman.com/strategy-pattern-csharp/

https://github.com/pcmichaels/StrategyExample

Using the Builder Pattern for Validation

When doing validation, There’s a number of options to how you approach it: you could simply have a series of conditional statements testing logical criteria, you could follow the chain of responsibility pattern, use some form of polymorphism with the strategy pattern, or even, as I outline below, try using the builder pattern.

Let’s first break down the options. We’ll start with the strategy pattern, because that’s where I started when I was looking into this. It’s a bit like a screwdriver – it’s usually the first thing you reach for and, if you encounter a nail, you might just just tap it with the blunt end.

Strategy Pattern

The strategy pattern is just a way of implementing polymorphism: the idea being that you implement some form of logic, and then override key parts of it; for example, in the validation case, you might come up with an abstract base class such as this:

public abstract class ValidatorBase<T>
{        
    public ValidationResult Validate(T validateElement)
    {
        ValidationResult result = new ValidationResult();
 
        if (CheckIsValid(validateElement))
        {
            result = OnIsValid();                
        }
        else
        {
            result = OnIsNotValid();
        }
 
        return result;
    }
 
    protected virtual ValidationResult OnIsValid()
    {
        return null;
    }

    . . .

You can inherit from this for each type of validation and then override key parts of the class (such as `CheckIsValid`).

Finally, you can call all the validation in a single function such as this:

public bool Validate()
{
    bool isValid = true;
 
    IEnumerable<ValidatorBase> validators = typeof(ValidatorBase)
        .Assembly.GetTypes()
        .Where(t => t.IsSubclassOf(typeof(ValidatorBase)) && !t.IsAbstract)
        .Select(t => (ValidatorBase)Activator.CreateInstance(t));
 
    foreach (ValidatorBase validator in validators)
    {
        ValidationResult result = validator.Validate();
        if (!result.IsValid)
        {
            isValid = false;
            Errors.AddRange(result.Errors);
        }
 
        if (result.StopValidation)
        {
            break;
        }
    }
 
    return isValid;
}

There are good and bad sides to this pattern: it’s familiar and well tried; unfortunately, it results in a potential explosion of code volume (if you have 30 validation checks, you’ll need 30 classes), which makes it difficult to read. It also doesn’t deal with the scenario whereby one validation condition depends on the success of another.

So what about the chain of responsibility that we mentioned earlier?

Chain of responsibility

This pattern, as described in the linked article above, works by implementing a link between a class that validates your data, and the class that will validate it next: in other words, a linked list.

This idea does work well, and is relatively easy to implement; however, it can become unwieldy to use; for example, you might have a class like this:

private static bool InvokeValidation(ValidationRule rule)
{
    bool result = rule.ValidationFunction.Invoke();
    if (result && rule.Successor != null)
    {
        return InvokeValidation(rule.Successor);
    }
 
    return result;
}

But to build up the rules, you might have a series of calls such as this:

ValidationRule rule2 = new ValidationRule();
rule.ValidationFunction = () => MyTest();

ValidationRule rule1 = new ValidationRule();
rule.ValidationFunction = () => MyTest();
Rule.Successor = rule2;

As you can see, it doesn’t make for very readable code. Admittedly, with a little imagination, you could probably re-order it a little. What you could also do is use the Builder Pattern…

Builder Pattern

The builder pattern came to fame with Asp.Net Core; where during configuration, you could write something like:

services
    .AddMvc()
    .AddTagHelpersAsServices()
    .AddSessionStateTempDataProvider();

So, the idea behind it is that you call a method that returns an instance of itself, allowing you to repeatedly call methods to build a state. This concept overlays quite neatly onto the concept of validation.

You might have something along the lines of:

public class Validator
{
    private List<ValidationRule> _logic;        
 
    public ValidatorEngine AddRule(Func<bool> validationRule)
    {
        ValidatorLogic logic = new ValidatorLogic()
        {
            ValidationFunction = validationRule
        };
        _logic.Add(logic);
 
        return this;
    }

So now, you can call:

myValidator
    .AddRule(() => MyTest())
    .AddRule(() => MyTest2())
    …

I think you’ll agree, this makes the code much neater.

References

http://blogs.tedneward.com/patterns/Builder-CSharp/

http://piotrluksza.com/2016/04/19/chain-of-responsibility-elegant-way-to-handle-complex-validation/