Friday 4 March 2011

Comparing fluent interfaces for guard clauses [part 4]

In the last post on fluent guard checks I showed an interface that aggregates state, removing the trapdoor effect associated with multiple guards. It works, but might in some environments be an unnecessary contributor to memory pressure.

Performance-tweaked fluent chained guards

Rick Brewster came up with an alternative syntax that only instantiates a state object on the first fail. Otherwise, it just passes null. Again, the guard checks are extension methods that hang off the state object – even (I didn’t realise this worked) if the state object is null:

Validate.Begin()
    .IsNotNull(message, "message")
    .SomeOtherCondition(message, "message")
    .Check();

The state object looks like (in this case, a simple equivalent – Rick’s is more sophisticated):

public class Validation
{
    private _exceptions = new List<exception>(1);
    public List<exception> Exceptions
    {
        get { return _exceptions; }
}

Validate.Begin() looks like:

public static Validation Begin()
{
    return null;
}

An example guard check looks like:

public static Validation IsNotNull(
    this Validation state, 
    object value, 
    string name)
{
    if(value == null)
    {
        if(state == null)
        {
            state = new Validation();
        }
        state.Exceptions
            .Add(new ArgumentNullException(name));
    }
    return state;
}

Check() just checks for any exceptions, and throws a ValidationException if there are any, which wraps the Exception list -- just like in part 3.

So, because the argument value and name aren't in the state object they need to be explicitly passed into each guard check; the check code is also more complicated because it does more than one thing.

This makes the syntax a little less clear to me, with a would-be-good-if-it-were-redundant Validate.Begin() always starting a guard chain, and with argument value and name sometimes appearing repeatedly.

Roundup

So, the decision about whether to avoid creating an unnecessary state object determines to some extent how clear that syntax is. Deciding whether to break fast or accumulate guard state just means that you might need to have something to terminate the chain.

Whether you really need to avoid the state object creation is really app-specific; you’d need to think and test. I’ve hit the need for chained guard checks a number of times though, so I’d definitely look to implement that. My ideal solution is somewhere between the two.

Also interesting: www.bikeshed.org.

Comparing fluent interfaces for guard clauses [part 3]

A fluent interface helps simplify the expression of multiple guard checks, but doesn’t avoid the trapdoor effect in which the first guard fail causes a break – because none of the guard state is propagated from check to check.

Aggregating state

To avoid the trapdoor problem and aggregate the guard result state as it’s passed down the chain, then break if needed in some chain terminator.

The state object could just contain a list of exceptions to add to:

public class GuardState
{
    private _exceptions = new List(1);
    public List Exceptions
    {
        get { return _exceptions; }
    }

    public object Value { get; set; }
    public string Name { get; set; }
}

Typical guards would then just add an exception to the list and pass it on:

public static GuardState IsNotNull(
    this GuardState state)
{
    if(state.Value == null)
    {
        state.Exceptions
            .Add(new ArgumentNullException(state.Name));
    }
    return state;
}

Finally, we need to terminate the guard chain and take action:

public static void Check(this GuardState state)
{
    if(state.Exceptions.Count > 0)
    {
    	var ex = new GuardStateException(state.Exceptions);
	throw ex;
    }
}

This means you can now gather all useful state in one go before throwing, which then means you have a chance of solving multiple problems before releasing a fix. This is a rough draft – for example you might want to only instantiate the exception list on the first fail to limit memory usage – but it’s usable.

If it’s used in a high throughput environment memory pressure might be important, even though the guard state objects wouldn’t make it out of gen0. Rick Brewster came up with a syntax that sacrifices a little clarity to tweak the memory use of his guard interface – which I’ll talk about briefly in the next post.

Comparing fluent interfaces for guard clauses [part 2]

So Microsoft provide a Guard class that simplifies guard checks. It has a simple interface, but is a bit restricted and can look a bit clunky if you need to do multiple checks -- assuming you've extended the Guard class:

Guard.ArgumentNotNull(message, "message");
Guard.Contains("XYZ", message, "message");
// ...

We can simplify these chains a lot by using a fluent interface.

Fluently chaining guards

A fluent interface can be used to chain checks. It’d look something like this:

Guard.Argument(message, "message")
    .IsNotNull()
    .SomeOtherCondition();
Guard.Argument(count, "count")
    .IsPositive();

The guard checks are extension methods hanging off the underlying state object that’s passed from check to check. The state object is populated by Argument(…), and holds the argument value and name:

public class GuardState
{
    public object Value { get; set; }
    public string Name { get; set; }
}

and an example guard check looks like:

public static void IsNotNull(this GuardState state)
{
    if(state.Value == null) 
    { 
        throw new ArgumentNullException(state.Name);
    }
}

So with this technique I could simplify chained guard checks, but the code would break on the first guard fail. CuttingEdge.Conditions is a freely-available library that does much the same thing, in, I’d guess, the same way.

In some sense there’s not much difference between using this, and just using repeated calls to specific IsNotNull(value, “name”)  methods. To make it more useful, we’d need to start aggregating state and avoiding the guard trapdoor effect.

Comparing fluent interfaces for guard clauses [part 1]

Urgh, not again:

public void SomeMethod(string message)
{
    if (message == null)
    {
        throw new ArgumentNullException("message");
    }
}

Guard clauses are clunky. They’re also like a series of trap doors – you break on the first guard, patch and release only to find that you break on the next.

For the clunkiness, we could Extract Method, making things clearer:

public void SomeMethod(string message)
{
    IsNotNull(message, "message");
}

public void IsNotNull(string argumentValue, string argumentName)
{
    if (message == null)
    {
        throw new ArgumentNullException(argumentName);
    }
}

Eventually we might collect a few and gather them under a static class, as they're not state-dependent:

Guard.IsNotNull(message, "message");

And helpfully, there is a lightweight simplifying Guard class in the Microsoft.Practices.Unity app block: the Guard static class provides a series of methods for basic guard checks.

Guard.ArgumentNotNull(message, “message”);

The Guard class only provides a limited range of checks – although it’s partial so could be extended. The interface is pretty simple though, and provides a good starting point.

However, if you need to make a series of guard checks the interface gets cluttered with a series of Guard references and reused arguments. That can be made a bit clearer with a simple fluent interface.