Pages

Wednesday, 18 November 2009

Reach Out and Touch A Developer!

I can only imagine what you're expectations are of this post given the title! You may be reading this for entirely the wrong reasons. If so, remember, Google is your friend.

Over the weekend I caught the DDD bug and started buying books, subscribing to blogs etc. As part of my random hops I stumbled upon Stephen Oakman of The Agile Workshop. He says in his Contact Us page that anyone is welcome to just pop in if they're passing. Having found myself in Cambridge yesterday lunchtime I did just that. Bit of a risk || leap of faith but I thought, hey, why not?

Turned out to be a fantastic use of a lunch hour. Once they'd gotten over the shock of someone actually taking them up on their offer we settled into some truly geeky discussions.

So, why on earth am I blogging about this?

Simple: if you work remotely you need to actively build a network of peers.

With the advent of Skype, Mikogo etc. remote working has never been so productive; but a developer in this environment still won't have a pool of knowledge comparable to, say, working in a large, office-based company. The guys at The Agile Workshop not only make half-decent coffee but seem pretty spot-on in many fields of software development that I am passionate about. They also loaned me a raft of books from their 'library', which I will return - honest :).

Here's to a mutually beneficial relationship.

Tuesday, 3 November 2009

2 Week Sprints!

Both of our applications that use the Scrum development framework have now halved their iteration cycles from 4 weeks to 2 weeks.

This felt rather daunting at first. I was worried that there just wouldn't be enough time to actually develop something of billable, business value for our customers. However, I have been pleasantly surprised by the universal acceptance of this change. Developers, analysts and managers all report to less confusion about the relevant content of the Product Backlog - this has many cross-overs with some Getting Things Done principles regarding removing clutter.

With this one simple process change we now feel much more 'sprinty': able to really focus on a smaller number of work items. We have also doubled the amount of feedback measured and adaption possible; velocity is also more meaningful.

So, highly recommended. I wonder if we'll move to a one week sprint as Ken Schwaber currently recommends? Xtreme sprinting!

Thursday, 22 October 2009

DevExpress CodeRush and Refactor! Pro Review

I've been taking a look at this 2-product package from DevExpress over the last couple of weeks. These are my findings...

Pros
  • Adding cyclomatic complexity numbers to the left-hand margin of members was very nice. This gives you immediate awareness of whether your method needs to be refactored.
  • The Metrics window allows you to see any of the 8 measures for an entire class and then double click a member to dig down into the code. This I liked a lot.
  • Adding contracts to methods was reasonable.
  • Automatically greying out unused or unnecessary code (including namespaces, contexts and members) was very nice.
  • Inline ability to suppress suggestions for a varying scope was good.
  • Pull Member up. Lists parent classes to move a member to.
  • "Introduce a using statement" (to an IDisposable object) worked extremely well.
Cons
  • Initial thoughts are that it hides poorly written code and, thus, detracts from Craftsmanship.
  • I removed all the vertical connecting lines - far too messy.
  • The suggestion to make some variables inline was wrong. It makes the code harder to understand and, anyway, the compiler will do it.
  • The jump / break / return pointers are interesting and pretty, but it simply validates overly complicated code.
  • The suggestion to replacing objectName + ".sql" with string.Format("{0}.sql", objectName) is not necessary. Strings are, indeed, immutable; but you can concatenate them efficiently during the instantiation.
  • Suggestions to remove this. from variables - I didn't like that. I don't qualify methods with this, but I do for properties and fields. It would have been nice to separate the features.
  • I removed the Region Painting functions as it was less clear than VS's inbuilt features.
  • Disabled the Structural Highlighting. If you need an icon next to the word private to tell you that it's private then you really shouldn't be a developer!
  • Circular suggestions. Having converted a newed-up object to use Initialisers it then changed the suggestion to decompose it!
Wish List
  • A prompt to automatically end a #region. including the text e.g. #endregion Constructors.
  • Context-sensitive help in the Options dialog please.
  • Ability to add multiple metrics rather than just Cyclomatic Complexity or Line Count etc. to the left-hand margin of classes.
  • In the Option dialog identification of Level in the tree view would help.
  • A refactoring routine to create the protected On() method for events.
Conclusions? Well, overall, not bad at all. I thought I wouldn't like the interaction and the perceived lack of control; but it was actually pretty easy to use. It does take a while to learn. You just have to get stuck into some code and see what it suggests. Soon you'll find yourself wondering whether it can do xyz for you - normally it can. I, personally, will be keeping it.

My biggest fear is that too many of the features are there just to mask bad code design.

Tuesday, 20 October 2009

TFS 2010 Beta 2 - Basic Edition

Just a very quick to note about the new version of TFS called 'Basic'. Lots of people blogging about it but, for me, the biggest feature is it's ability to install on a non-server OS.

Very cool.

Now you can run a local copy (with all the loveliness you're used to) for all those little projects that aren't really the property of your employer!

Sunday, 18 October 2009

A Fireside Conversation

"I had a wonderful dream last night."

"Tell me more" you say as you lean a little closer.

"Well, I dreamt that I lived in this wonderful fantasy world full of unicorns and faeries. Every day was perpetual spring and the streams ran clear and cool. I had two close neighbours and each morning one would bake bread and the other would fry bacon. Disease and crime were a thing of the past. Best of all, though, was that every public member of Microsoft's entire Base Class Library now implemented an interface."

"No way!"

"Seriously, the unicorns were beautiful."

"No, I mean the bit about the interfaces."

"Really? What, you find the rest of my utopian landscape somehow more plausible?"

"Um... yes."

"Hmm..."

"But now you mention it; that would be quite something. Imagine how easy IoC and DI would become? Unit Tests would flow from our fingers like olive oil. Simple, elegant Adapter Patterns would fill the skies like flights of swallows."

"I can almost see them."

"It can't be that difficult, can it?"

[Pause]

"Anyway, another pint?"

Tuesday, 13 October 2009

Enabling Code Coverage on TFS Build Server Without VS Test Edition

Back in May 2009 I exchanged a number of emails with Buck Hodges regarding Code Coverage on my build server. Here's my original blog: Oi Microsoft, this IS part of Development!. Basically, the upshot was if you don't have Visual Studio 2008 Test Edition installed on your build server you will not be able to run Code Coverage as part of your automated builds.

Well, I've now managed it.

To be honest I'm not exactly sure how this happened! Inside my Default.TestRunConfig file I had my main (ASP.Net MVC) project enabled. Recently, I have added more projects to my solution and their respective \bin\debug\ dlls have been automatically added to the Code Coverage list of artifacts to instrument. I then noticed that Code Coverage results were appearing in the build for these new libraries. No coverage for my main project though. The final stage was to remove the Code Coverage reference to the main project and, instead, target the resultant dll.

I now have full unit testing and code coverage on my entire solution - a result that, apparently, can't happen.

Wednesday, 7 October 2009

Dependency Inversion Pattern Clarification

Given the following 2 dependancy structures...

interface IDependancy
{
}
class DefaultDependancy : IDependancy
{
}

... I have seen many Dependency Inversion (DI) patterns implemented in the follow way...

class Worker
{
    private IDependancy _dependancy;

    Worker()
        : this (null)
    {
    }

    Worker(IDependancy dependancy)
    {
        if (dependancy == null)
            _dependancy = new DefaultDependancy();
        else
            _dependancy = dependancy;
    }
}

I'm also guessing that you've probably gotten this far, thought "seems about right" and are about to flip back to see if anything new's happened on Twitter? Well, hold on - 'cos you're wrong!

The problem with the above scenario is that it doesn't correctly convey the intention of the pattern. The content of the non-default constructor is being asked to cope with two, entirely different, situations.

  1. "Did the client intentionally, and knowingly, call the default constructor" or
  2. "Did the client call the non-default constructor directly and accidentally pass in a null reference?"

This is a perfect recipe for the most wonderful 'managed' error: NullReferenceException. This will be made even more troublesome if you haven't yet switched to using small methods as you'll have no idea what's null. Enjoy!

So, here's what you should be doing ...

class Worker
{
    private IDependancy _dependancy;

    Worker()
        : this(new DefaultDependancy())
    {
    }

    Worker(IDependancy dependancy)
    {
        if (dependancy == null)
            throw new ArgumentNullException("dependancy");

        _dependancy = dependancy;
    }
}

Now we know that if the non-default constructor's sole parameter is null then it's because there's a problem. Actively throwing our own ArgumentNullException also allows us to take control of the situation and name the offending variable.<

This simple change removes any ambiguity in your code and makes your intentions abundantly clear.