Question

Right now I'm working on a web application that receives a significant amount of data from a database that has a potential to return null results. When going through the cyclomatic complexity for the application a number of functions are weighing in between 10 - 30. For the most part the majority of the functions with the high numbers have a lot of lines similar to the following:

If Not oraData.IsDBNull(4) Then row("Field") = oraData.GetString(4)

Which leads me to my question, what is the best way to go about trying to bring these numbers down? Right now I'm looking at having the majority of the functions below 10.

Was it helpful?

Solution

What about using Extension Methods.

Imports System.Runtime.CompilerServices

Module Extensions

    <Extension()> _
    Public Function TryGetString(ByVal row As IDataRecord, i As Integer) As String
        If row.IsDBNull(i) Then
            Return null
        End If
        Return row.GetString(i);
    End Function

End Module

Then you can simply write:

row("Field") = oraData.TryGetString(4)

This reads smoothly and reduces cyclomatic complexity on your functions.

OTHER TIPS

Decompose into functions, perhaps something like this:

//Object Pascal
procedure UpdateIfNotNull( const fldName: String; fldIndex : integer );
begin
  if oraData.IsDBNull( fldIndex ) then
    row( fldName ) := oraData.GetString(fldIndex);
end;

Of course you can extend the procedures signature so that "oraData" and "row" can passed as parameters.

The first question is: Why are you "hung" up on CC ? It's a tool to evaluate how dense the code is and a rule of thumb should be "not too high of a cc number".

It's probably hitting all those "IF"s and bringing up that number - so reduce the number of ifs by calling a wrap function that extracts the data from the result set which handles the null or change the query so it doesn't return nulls.

Keep in mind that nulls do provide information and are not useless. For example Republican or Democrat ? using null says neither choice.

Did you see this question? He's asking something similar (but I think at a more basic level) ... but then that means the answers there may not be much help here.

I would definitely agree with the other suggestions here: if there are repeated statements that can be neatly packaged into functions/procedures, that might be one approach to take, as long as you're not just shifting CC around. I'm not sure you've gained too much if you move from one proc with a CC of 35 to three procs with CCs of 15, 10, and 10. (It's not a bad first step, but ideally you'd be able to simplify something on a larger scope to reduce total CC in that area of your system.)

It is possible to refactor the if into a separate utility function to reduce your CC. A number of functions or a function relying on type differentiation might be required to handle the different database types ( string, int etc ..)

However, I would argue that any solution would result in less maintainable or readable code (i.e. you might worsen other metrics!) and would as QA allow it to pass according to this justification.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top