A Day In The Lyf

…the lyf so short, the craft so longe to lerne

Archive for August 2007

Throw Out Those Utility Classes

How many times have you written an xxxUtils class, where xxx is some framework supplied class that you can’t extend or subclass? I always seem to end up with several in any decent sized project, StringUtils, DateUtils, DictionaryUtils, etc. In most cases, these classes are the result of language limitations. In Ruby and Smalltalk, for example, what would be the point of a StringUtils class when you could simply add methods to the String class directly? But C# and Java make String sealed (final) so you can’t even subclass it.

Utility classes like these tend to suffer from logical cohesion. In spite of the friendly-sounding name, logical cohesion is actually a fairly weak form of cohesion; it’s just a loose jumble of functions that have something in common. It can in no way be considered object-oriented.

Our DictionaryUtils makes an interesting case study because it was small. It only did two things: compared two dictionaries key-by-key for equality (useful in testing), and converting the entries to a Ruby-esque string. That last method made me a little jealous of how convenient Hashes are in Ruby:

middlestate:~ bhbyars$ irb
>> {'a' => 1, 'b' => 2, 'c' => 3}
=> {"a"=>1, "b"=>2, "c"=>3}

For the non-Ruby readers, I just created a 3-element Hash in one line. The command-line interpreter spit out a string representation. Our DictionaryUtils.ConvertToText could manage that last bit, but I wanted to be able to create hashtables as easily in C# as I could in Ruby. Naturally, that meant a third method on DictionaryUtils. Or did it?

C# on Hash

DictionaryUtils.Create seemed bloviated and ugly as soon as I first wrote it, so I quickly scratched it out and started a new class:

public class Hash
{
    public static Hashtable New(params object[] keysAndValues)
    {
        if (keysAndValues.Length % 2 != 0)
            throw new ArgumentException(“Hash.New requires an even number of parameters”);

        Hashtable hash = new Hashtable();
        for (int i = 0; i < keysAndValues.Length; i += 2)
        {
            hash[keysAndValues[i]] = keysAndValues[i + 1];
        }
        return hash;
    }
}

This allowed me to create small loaded Hashtables in one line, which was convenient, especially for test methods (although the syntax isn’t as explicit as Ruby’s). I then decided to merge the static DictionaryUtils methods into Hash, as instance methods. First, of course, I had to make Hash an actual dictionary implementation. This was trivial:

private IDictionary proxiedHash;

public Hash(IDictionary dictionary)
{
    proxiedHash = dictionary;
}

public bool Contains(object key)
{
    return proxiedHash.Contains(key);
}

public void Add(object key, object value)
{
    proxiedHash.Add(key, value);
}

public void Clear()
{
    proxiedHash.Clear();
}

// etc…

Then I changed the return value of Hash.New to a Hash instead of a Hashtable. The last line became return new Hash(hash) instead of return hash.

Next I moved the ConvertToText method, which, as an instance method, conveniently mapped to ToString.

public override  string ToString()
{
    SeparatedStringBuilder builder = new SeparatedStringBuilder(", ");
    ICollection keys = CollectionUtils.TryToSort(Keys);
    foreach (object key in keys)
    {
        builder.AppendFormat("{0} => {1}", Encode(key), Encode(this[key]));
    }
    return "{" + builder.ToString() + "}";
}

private object Encode(object value)
{
    if (value == null)
        return "<NULL>";

    IDictionary dictionary = value as IDictionary;
    if (dictionary != null)
        return new Hash(dictionary).ToString();

    if (value is string)
        return "\"" + value + "\"";

    return value;
}

The SeparatedStringBuilder class is a StringBuilder that adds a custom separator between each string. It’s very convenient whenever you’re a building a comma-separated list, as above. It’s proven to be handy in a variety of situations. For example, I’ve used it to build a SQL WHERE clause by making ” AND ” the separator. It’s included with the code download at the bottom of this article.

Notice, also, that we’re still using a CollectionUtils class. Ah, well. I’ve got to have something to look forward to fixing tomorrow…

The DictionaryUtils.AreEqual method conveniently maps to an instance level Equals method:

public override bool Equals(object obj)
{
    IDictionary other = obj as IDictionary;
    if (other == null) return false;
    Hash hash = new Hash(other);
    return hash.ToString() == ToString();
}

public override int GetHashCode()
{
    return proxiedHash.GetHashCode();
}

The syntax is much cleaner than the old DictionaryUtils class. It’s nicely encapsulated, fits conveniently into the framework overrides, and is object-oriented, allowing us to add other utility methods to the Hash class easily. It’s especially nice for testing, since the Equals method will work against any dictionary implementation, not just Hashes:

Assert.AreEqual(Hash.New(“address”, customer.Address), propertyBag);

The approach was simple, relying on proxying for fulfilling the IDictionary implementation (I’m probably abusing the word “proxying,” since we’re not doing anything with the interception. Really, this is nothing more than the Decorator design pattern). That was easy only because the framework actually provided an interface to subtype; the same isn’t true of String and Date. However, it isn’t true of StringBuilder either; if you look at the code, SeparatedStringBuilder looks like a StringBuilder, it talks like a StringBuilder, and it quacks like a StringBuilder, but there is no syntactic relationship between them since StringBuilder is sealed and doesn’t implement an interface. While the need for SeparatedStringBuilder may represent a special case, I think I’d prefer creating similar-looking objects rather than relying on a framework-provided xxx and a custom built xxxUtils class. Proxying, as used by Hash, generally makes such implementations trivial and clean, leaving you to spend your time developing what you really want without making the API unnecessarily ugly.

All the code needed to compile and test the Hash class can be found here.

Written by Brandon Byars

August 28, 2007 at 11:40 pm

Posted in .NET, Design

Tagged with

Dealing with Exceptions

We had an interesting discussion on the XP news group this past week about dealing with exceptions. The discussion seemed to focus on functions that return something rather than functions called for their side effects. Four general approaches were mentioned:

Return a special value (null or an error code)

This was generally seen as the weakest approach. Returning a null forces a null-check on each client of your method, which has the unfortunate effect of distributing complexity instead of localizing it. The canonical example is with lists—it is much better to return an empty list than a null one. Client code can work without any changes with an empty list. The same principle applies to error codes.

Throw an exception

This was the most controversial option. Several developers argued that exception handling is prone to the same weakness as the special return value, that it spreads complexity around. As Ron Jeffries’ said: “Throwing an exception doesn’t solve the problem any more than throwing up in the morning solves one’s drinking problem.”

Nevertheless, throwing an exception has proven to be the mainstream choice in modern languages, and the way exceptions bubble up the call stack can come in handy when used judiciously. Anthony Williams advocated using them, noting that they clearly signal an abortive operation (rather than relying on clients to check a return value), and allow application developers to write a global exception handler that catches any uncaught exceptions throughout the application.

The discussion intrigued me largely because I continue to use exceptions when convenient, although I’m interested in learning alternative approaches. I think that at least some of the hostility towards exceptions can be traced to the ugliness of checked exceptions (as in Java), which force clients to write try/catch blocks even if they’d prefer the exception bubble up.

Return a polymorphic value

This is probably the purest object-oriented solution, but I’m skeptical that it can work as a general case. Woolf’s Null Object Pattern is a special case—the empty list mentioned above being a simple example. We use a more sophisticated example in the content management system we developed for our website at work. When you go to ”/Content/AboutUs,” for example, the application knows “AboutUs” is supposed to be a content-managed page, and requests the content from the database. If the page doesn’t exist, rather than return null or throw an exception, it returns a new web page whose content matches our 404 page content.

If a page is content-managed, then users can edit it directly on the page in a fairly typical way. The content-managed portion is outlined with an ‘edit’ link at the top that puts the content in a WYSIWYG editor. However-this is the crucial point-the web page returned when it doesn’t exist in the database is a content-managed page. Yes, it has the 404 content, and anybody visiting that URL without content editing privileges sees what they are supposed to see. But if you do have content editing privileges, you see the familiar border with the edit link, and you can use the exact same procedure that you use to update other pages to create new pages.

The advantage to this approach is obvious—clients do not need to behave any differently regardless of whether the method call succeeded or failed. It was suggested that perhaps the same approach could be used even if some other exception occurred. I think in some cases it may be possible. I looked over some of our code for an example only to discover that the large majority of methods we use that throw exceptions have a void return type, but found an example of an exception-throwing method in our credit card processing code. The code simply sends an XML document to the company we use to process credit cards and returns a value representing the result of that transaction. It looks something like this:

public CreditCardResponse Send(string xml)
{
    IServerXMLHTTPRequest server = GetServer();
    try
    {
        server.send(message);
    }
    catch (Exception ex)
    {
        throw new ApplicationException("connection failed");
    }
    return Parse(server.responseText);
}

This code clearly could benefit from removing the thrown exception and enhancing or subclassing CreditCardResponse. That return type is already responsible for reporting errors given in the return XML by the credit card processor; why would clients want to treat failing to connect to the credit card processor any differently than one of those errors?

Callbacks

At first glance, I don’t see why a callback would be any easier than an exception handler for dealing with errors, other than perhaps making it easier to localize handling certain exceptions in one place. They have the unwanted effect of cluttering up the API by adding exception handling callback parameters.

Written by Brandon Byars

August 27, 2007 at 9:35 pm

Posted in Design

Follow

Get every new post delivered to your Inbox.