The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

Archive for the 'NDepend' Category

NDepend 3 Preview

Posted by Davy Brion on 28th January 2010

I was just playing around with an NDepend 3 beta version to experiment with the new Visual Studio integration that the NDepend team has developed. 

Once you install the Visual Studio addin through the VisualNDepend.exe tool, you’ll notice the following menu has been added in Visual Studio:

01

If you select the first item, you can easily create a new NDepend project for your current solution:

02

You’ll also notice an NDepend icon in the bottom-right corner of Visual Studio.  Clicking on it shows you an immediate overview of NDepend’s CQL query results for your solution:

 03

Clicking on the Show SQL Explorer immediately brings you to this view, which many NDepend users will recognize:

04

You can also right-click on a type (or a method) and you’ll see the following NDepend context-menu:

05

Which in turn allows you to open many of the familiar NDepend views:

06

This particular view is something that i find extremely useful.  Notice how you get an immediate overview of relevant metrics when you click on one of the items in the graph.  Or you can look at the metrics view:

 07

I’ve never understood how to interpret this view, but NDepend users who do will be glad to know they can now access it extremely easily :)

One thing that i can see myself make extensive usage of are the following features:

08

I’ve only played around with it for about 15 minutes now, but i’m impressed.  I never really liked NDepend 2 because i always got completely lost in the VisualNDepend UI.  Now that i have all of this integrated in Visual Studio, it just seems much easier to get to the information i really want.  And if you have to review a lot of code (like me), then this new NDepend version is sure to save you a lot of time.   It’s pretty much everything you’ve always wanted or already loved from NDepend, but much more easily accessible.

I did notice some small visual glitches (which might be related to running this in a VMWare virtual machine on OS X) and at one time even a Visual Studio crash, but i’m sure those issues will be fixed before the final release.

Oh, and i’m also very happy to note that this particular issue has also been resolved :)

Posted in IDE, NDepend | No Comments »

NDepend And Lack Of Cohesion Of Methods… Not to be trusted

Posted by Davy Brion on 11th December 2009

I already mentioned that i don’t trust the Lack Of Cohesion Of Methods (LOCM) metric from NDepend on the type level.  Let’s go over a small example, shall we?

Suppose you have a class like this:

    public class CohesiveClass

    {

        private List<int> integers;

 

        public CohesiveClass()

        {

            integers = new List<int>();

        }

 

        public void AddInteger()

        {

            integers.Add(integers.Count);   

        }

 

        public IEnumerable<int> GetEvenIntegers()

        {

            return integers.Where(i => i % 2 == 0);

        }

 

        public IEnumerable<int> GetOddIntegers()

        {

            return integers.Where(i => i % 2 > 0);

        }

    }

 

If you look at the NDepend LOCM documentation, you can find the following statement:

a class is utterly cohesive if all its methods use all its instance fields

Now, unless i’m missing a fundamental concept here, i would dare to claim that the class shown above is utterly cohesive.  After all, each method uses the 1 instance field of this class.

This is how NDepend is supposed to calculate the LOCM metric (taken from the documentation):

There are several LCOM metrics. The LCOM takes its values in the range [0-1]. The LCOM HS (HS stands for Henderson-Sellers) takes its values in the range [0-2]. A LCOM HS value highest than 1 should be considered alarming. Here are algorithms used by NDepend to compute LCOM metrics:

  • LCOM = 1 – (sum(MF)/M*F)
  • LCOM HS = (M – sum(MF)/F)(M-1)

Where:

  • M is the number of methods in class (both static and instance methods are counted, it includes also constructors, properties getters/setters, events add/remove methods).
  • F is the number of instance fields in the class.
  • MF is the number of methods of the class accessing a particular instance field.
  • Sum(MF) is the sum of MF over all instance fields of the class.

The underlying idea behind these formulas can be stated as follow: a class is utterly cohesive if all its methods use all its instance fields, which means that sum(MF)=M*F and then LCOM = 0 and LCOMHS = 0

I may suck at math, but i think that both LCOM and LCOM HS should be 0 for the code shown above.  NDepend however disagrees with me.  LCOM for this class, as calculated by NDepend is 0.33 and LCOM HS is 0.4.  In both cases NDepend considers these values to be bad for this class (as indicated by the fact that the IsBadLackOfCohesionOfMethods and IsBadLackOfCohesionOfMethods_HS values in TypesMetrics.xml are set to True).

Of course, it also reports that there are 3 fields in this type, instead of one (NFields is set to 3) and 2 static methods along with the 4 instance methods.  I’m sure you can agree with me that there are no static methods, and only one field.

Now, if you look at the compiled code in reflector, it suddenly makes sense:

reflector_output

Alright, so we do have 3 fields: my integers list, and 2 Func instances that the C# compiler generated for me.  And the 2 static methods that were listed by NDepend also show up, and they contain the code of my lambda expressions.

Now here is my question: if a tool calculates metrics of code, shouldn’t it calculate them based on the code that i wrote, instead of the code that the compiler generated?  Especially when it comes to metrics that are supposed to give you an idea on the quality of the code, i would really prefer it that my code was used for the calculation, without the compiler generated code.

Let’s try to make NDepend agree with me that this code is indeed utterly cohesive, shall we?

Here’s a modified version of the code:

    public class CohesiveClass

    {

        private List<int> integers;

 

        public CohesiveClass()

        {

            integers = new List<int>();

        }

 

        public void AddInteger()

        {

            integers.Add(integers.Count);   

        }

 

        public IEnumerable<int> GetEvenIntegers()

        {

            var evenInts = new List<int>();

 

            foreach (var i in integers)

            {

                if (i % 2 == 0)

                {

                    evenInts.Add(i);

                }

            }

 

            return evenInts;

        }

 

        public IEnumerable<int> GetOddIntegers()

        {

            var evenInts = new List<int>();

 

            foreach (var i in integers)

            {

                if (i % 2 > 0)

                {

                    evenInts.Add(i);

                }

            }

 

            return evenInts;

        }

    }

 

NDepend will now gladly agree with me that LCOM and LCOM HS are 0 and that the class is utterly cohesive.

I don’t know about you, but i’ll take version 1 over version 2 any day of the week.

Until this issue is fixed (and who knows how many other metrics show incorrect results based on compiler generated code), i’ll assess the quality of my code myself instead of depending on a tool, thank you very much.

Posted in NDepend | 9 Comments »

Which Code Metrics Do You Consider Important?

Posted by Davy Brion on 9th December 2009

I’m looking into which Code Metrics we should keep an eye on, or at least pay attention to.  Of all the metrics that NDepend offers, i only seem to find the following ones valuable (some only slightly):

  • On the Type level:
    • The number of lines of code of the type
    • Afferent coupling
    • Efferent coupling
    • Cyclomatic complexity
    • Association between classes
    • Number of children
    • Depth of inheritance tree
  • On the Assembly level:
    • Efferent coupling
    • Relational cohesion

Some metrics that you’d expect to be interesting but that i’m specifically not interested in:

  • On the Type level:
    • Lack of Cohesion Of Methods: i can’t help but think that this metric is calculated incorrectly.  When studying NDepend’s xml output, i noticed quite a few types where the number of instance fields was incorrect (it listed a lot more than there actually were, and it seems to be related to having compiler generated classes when you’re using lambda statements quite heavily).  Since the number of fields metric is used to determine the cohesion of the class, this result just doesn’t seem to be correct if the number of fields is incorrect.
  • On the Assembly level:
    • Afferent Coupling: our client-side and server assemblies share no types, except for the types declared in a common assembly.  That common assembly only contains Request/Response types and DTO’s, nothing else.  The afferent coupling of the common assembly is always high, though that metric is meaningless for us.  The afferent coupling of the client-side and server side assembly is 0 since they never use each other directly.  So basically, that metric is useless for us.
    • Instability: Instability is the ratio of efferent coupling to total coupling.  Since total coupling is the sum of efferent coupling and afferent coupling, it is in our case essentially the same as efferent coupling (because our afferent coupling is 0), which means that the ratio of efferent coupling to total coupling is 1, which is supposed to indicate a completely instable assembly.
    • Abstractness: this is the ratio of abstract types (abstract classes and interfaces) to the total number of types.  This is also useless for us since a very high percentage of our classes implements an interface, and usage of those classes always happens through the interface type instead of the concrete type
    • Distance From Main Sequence: this metric is based on instability and abstractness of an assembly… again, useless in our case.

I might be wrong about the whole thing, but i can’t help but think that these metrics are no longer relevant, or even present an incorrect picture about the quality of the code if you’re making heavy use of practices like Dependency Injection and tools like an Inversion Of Control container.

So i’d like to ask you: which metrics do you consider to be important? Which ones do you ignore?  Am i wrong about the ones i’ve listed as not interested in? Are there other metrics that you think i really need to take into account?

Posted in Code Quality, NDepend | 11 Comments »

I’ve been bought!

Posted by Davy Brion on 9th July 2008

Well no, not really, at least i hope not. Patrick Smacchia was kind enough to offer me a pro license for NDepend. If you don’t know that tool, go to the website and check it out. My experience with NDepend has so far been limited to once playing around with it for about 10 minutes and then realizing i would probably get hooked on it way too easily. So because of the price tag i quit experimenting with it. But now that i have a free license, i plan of playing around with it a lot. I’m pretty sure that there’s a lot of stuff in there that i’m gonna like a lot (especially the Code Query Language) so expect a few posts on NDepend in the near future. But, if there is anything in there that i don’t like or that i think could be better or that just gets on my nerves i will definitely make that very clear as well. That’s the price you pay if you give me a free license ;)

I might be willing to explore the pro’s and con’s of other development-related products as well ;) (*cough* DotTrace*cough*)

Posted in NDepend | 2 Comments »