July 7, 2008
@ 08:14 PM

The first time I heard of NDepend was on Hanselminutes (show here).  It sounded intriguing, but at the same time the show went into a lot of detail and used a lot of terminology that I wasn't familiar with, even with a computer science degree.  So it was with a little trepidation that I downloaded a copy and ran it against an application that I was working on at the time. 

To be honest, a bit of information overload was involved.  I could see that NDepend had gathered a lot of statistics regarding the code base, but I had no idea how to use it.  I didn't look at NDepend again for a few months.

The next time I saw NDepend was when I was looking at CI-Factory last year.  It was included as one of the tools in the continuous integration mix.  Same experience - information overload.

Just last week or so I took one more look at NDepend to see if it could help out with the code base I had inherited at work.  I had many places that needed refactoring, but it was hard to tell where to start.  My initial (3-minutes) reaction was the same - too much information after the analysis was complete.  I didn't know where to start.  But this time I stuck it out for more than 5 minutes - and that was all it took for me to fall in love (this time) with NDepend.  NDepend is largely based on "CQL" (Code Query Language), that sorta-kinda looks like SQL, but goes against code instead of a database (hmm... "LINQ to code" can't be very far off).  NDepend has several canned CQL statements that it runs as part of the analysis to help identify coding faux-pas, and the first query, with the description of "Quick summary of methods to refactor" was a treasure-trove of bad juju.  It identified methods that were too big, too complex, too... just about anything that can be quickly called out, and it picked the worst offenders to show.

NDepend1

NDepend2

NDepend3

NDepend showed me where the worst code was first.  That's what I got for sticking it out this time.  Now there are many, many more features that I have hardly scratched the surface of, and I hope to be able to cover those in later blog posts.  For now, just try out http://www.ndepend.com and check out your own FBI-most-wanted list.


 
Kick it! Digg it!  Categories: Agile | Refactoring

Look at the following piece of code:

private void DbMove(CopyInfo info)
{
    string targetDb = GetTargetDB(info);
    if (targetDb.Equals(string.Empty))
        return;

    PrepDbsForCopy(info.SourceDb, targetDb);

    GetAllData(info);
    if (IsNoSourceData())
        return;

    int upperBound = GetUpperBound();
    int rangeCount = GetRange();

    if (CopyNotCurrentlyPossible(_isDisconnected, _isHomogenous))
        return;

    DoAsyncDbCopy(info, upperBound, rangeCount, _isDisconnected, _isHomogenous);
}

Now this is a standard piece of code with several "short-circuit" returns in the code.  Short-circuiting is good, but usually only if it appears as the first instruction in the method, and only once.  Otherwise, refactoring the code (as above) is a bear.  Select a section of text to pull out (extract method), and if it contains a "return" or break, or anything like that, then you'll most likely get a complaint from your refactoring tool.  ReSharper 4 complains "Extracted block has exits to different points Proceed with refactoring?(sic)".  Besides the pain from lack of proper punctuation (just a typo, I'm sure), the pain of not being able to refactor when you want to is even worse.

However, you can refactor if you do some manual refactoring (and this is still easier than manually extracting the method).  Instead of:

    string targetDb = GetTargetDB(info);
    if (targetDb.Equals(string.Empty))
        return;

    ...

 

Try the following:

    string targetDb = GetTargetDB(info);
    if (targetDb.Equals(string.Empty))
        return;
   
else
   
{
       
...
    }

Then you can start using your refactoring tools like "Invert If"

    string targetDb = GetTargetDB(info);
    if (!targetDb.Equals(string.Empty))
   
{
       
...
    }
    e
lse
        return;

And "voila," your else can be tossed as cruft.  Do so with the other "if"s and yes, you have more indented blocks of code, but indented blocks of code can be easily refactored with "Extract Method."
 
Kick it! Digg it!  Categories: Agile | C# | Refactoring

I've found in the last few days that a name does mean something.  Not to "dis" Shakespeare, but some judicious renaming of Classes can change code-smell into a sweet smell.  The code does seem to talk, and classes or methods can sometimes say to you, "I'm not a 'foo', I', a 'bar'" - and simply making that change can make the code speak better to you.  Design emerges, and it makes it that much easier to maintain - either by you or others.  ReSharper makes refactoring things like this a joy!


 
Kick it! Digg it!  Categories: Agile | Refactoring