February 17, 2009

Agile Manifesto Wordle

I was looking over the Agile Manifesto and its twelve principles and decided to create a Wordle image of them to see what kind of buzz words emerged (click on the image to see a larger one):

AgileManifestoWordle

It’s interesting that change, customer, continuous, and done are some of the more prominent words.  It’s also cool that the words effective software development appear grouped together – forming a phrase that I’d say nicely sums up Agile practices.  :)

February 13, 2009

Handling Nulls and Optional Arguments in API Methods

When writing API methods that have arguments, keep the following two things in mind:

If arguments of a method are optional, overload the method so that the optional parameters don’t have to be passed and can instead use default values.  For instance if you have the following method:

public void DoStuff(string arg1, string arg2, string arg3) { … }

and arg3 is optional, overload DoStuff() so that it also includes a method like the following:

public void DoStuff(string arg1, string arg2) 
{
DoStuff(arg1, arg2, “something”);
}

Of course the first DoStuff() method listed should allow null to be passed for the optional arg3 and handle it appropriately, but it’s also nice to have the overload so that the user can automatically defer to a default value for the optional argument.

If arguments are required and should not be null, validate the arguments and throw an error if a null value is passed in for one of these arguments.  If you don’t do this checking, an error will be thrown later (probably a NullReferenceException), but the source of the error won’t be as obvious.  You’re better off failing early and making the cause of the error more explicit.  So at the start of the method, check all required arguments (that shouldn’t be null) for null values, and throw an ArgumentNullException if one of them is null.  For instance, if the first two arguments of the DoStuff() method are required and shouldn’t be null, do the following:

public void DoStuff(string arg1, string arg2, string arg3) 
{
if (arg1 == null)
throw new ArgumentNullException("arg1");
if (arg2 == null)
throw new ArgumentNullException("arg2");

// do stuff…
}

If an API method is overloaded, should all of the overloads do the null argument checking, or just one of them?  A colleague of mine prefers to have all of the methods do the checking, as the top of the exception stack trace then shows the exact method where the error occurred.  However, I prefer to have the one overloaded method that all the other overloads call do the checking, as it leads to less duplicate code.  Sure, the exact method overload that originally received the null argument might not be at the top of the exception stack trace, but it’s not too hard to look a row or two down to find it.  The .Net framework also follows this approach.  Check out the File class’s overloaded WriteAllLines() methods:

public static void WriteAllLines(string path, string[] contents) 
{
WriteAllLines(path, contents, StreamWriter.UTF8NoBOM);
}
public static void WriteAllLines(string path, string[] contents, Encoding encoding)
{
if (contents == null)
{
throw new ArgumentNullException("contents")
}

// write all of the lines...
}

The only downside that I see to this approach is that it could lead to scattered null checks if one of the overloaded methods takes additional required parameters that don't get passed to the other overloaded method.  Alternately, Rick Brewster describes a fluent approach to parameter validation, which allows you to consolidate some of this argument checking while also reporting when multiple arguments are invalid (as opposed to the approach above, where only the first invalid argument is reported).  Or you could utilize Spec# and its sweet  non-null types:

public void DoStuff(string! arg1, string! arg2, string arg3) { ... }

Writing API methods takes a little more consideration than stuff like private methods.  However, following the practices outlined above will make your API much better to work with.

February 12, 2009

Increasing Developer Interest in Continuous Integration Builds

Trying to fix a recent continuous integration (CI) build failure got me thinking about what motivates developers to fix broken builds.  Fixing broken builds as quickly as possible is a good practice, but it requires commitment from the entire development team.  So I was trying to think of ways to increase overall developer interest in fixing broken builds, and I thought of the following possibilities:

Rationalize: Add build metrics that track failures, length of time it takes to fix a build, amount of time the build stays green or broken, etc., and then report these metrics in a highly visible manner.  This might increase awareness and stress the significance of keeping builds green to developers who never realized or fully appreciated this importance.

Shame: Somehow call out the developer who broke the build and essentially embarrass him or her into fixing it (and hopefully scare him or her from breaking it again).  This worked out very well for me when I first started committing code, as I was terrified of breaking the build and having everyone consider me incompetent and inferior. 

Annoy: Pester people into fixing the build. For example, in my current project, an email is sent every time an error occurs.  This is done because if an error occurs, then something has gone very wrong and needs to be addressed immediately.  From my experience with developing and testing this project, it certainly does get annoying when your email inbox starts filling up in a hurry, and this absolutely motivates me to investigate and fix all issues as quickly as possible. 

Convenience: Make identifying build failures quicker and easier to do.  Add as much logging around the build as possible and present the results in a manner that is easily accessed and interpreted.  Making your unit test failures as descriptive as possible can also help here. 

Entertain: There are many different ways to make the build more enjoyable.  We used to have a siren that went off each time the build failed.  I'm not for certain if it motivated developers to fix the build, but it certainly increased awareness of broken builds—including awareness among non-developers.

Decree: Of course anyone who checked in code that is a part of a broken build should examine the build to see if he or she caused the failure.  However, you could just flat out declare that a broken build is every developer's top priority—all hands on deck.  This might be a little drastic and waste developer time, especially if the cause of the failure is easy to spot and fix, but it would at least ensure the broken build is receiving attention.

Fortunately I work with developers who care about our CI builds and strive to keep them green.  I have noticed, though, that the longer a build stays broken, the less interest there is in fixing the build.  This is a software "broken window", which The Pragmatic Programmer describes in the Broken Window Theory

In short, it has been shown that a broken window that is not fixed for a long time leads to larger crimes and destruction because the broken window conveys a sense of abandonment—as if the owner does not care about the building.  Thus police departments are being stricter on smaller crimes like breaking windows in hopes of preventing larger ones from occurring.  Similarly, we should be strict on small issues like broken builds and fix them as quickly as possible in order to prevent larger issues from appearing—and the more developers interested in fixing these issues, the better. 

Let me know how you cultivate interest in CI builds and handle other "broken windows".