Avoiding Nulls with Polymorphic Dispatch

When you return a Maybe<T>, clients have to deal with the non-existent case and so have a more complex API to deal with. That's why I think of the Maybe type as a tool of last resort. I much prefer to return a polymorphic object that just does the right thing.

For example, we're writing a little web application on top of SimpleWeb. We have written a WebServer class that dispatches an incoming Request to a WebService that can handle it. The WebService returns a WebResource that satisfies the request, and the WebServer tells the WebResource to write itself to an Response.

What should a WebService do when it can't find a resource corresponding to the requested URL?

We don't want to return null.

A WebService could return a Maybe<WebResource> but that complicates the WebService API and the code in the WebServer that interacts with WebServices. And what about all the other kinds of failure?

We thought about throwing a NotFoundException to the WebServer, which would translate it into a 404 response. But there are a lot of HTTP status codes and we didn't fancy defining an exception class for each one.

So we defined an ErrorWebResource that has a status code and an error message, and knows how to send back an error response. Now a WebService always returns a WebResource. The WebServer code doesn't know or care whether a WebResource represents the result of a successful request or an error. And we can easily support other status codes that require specific headers to be sent in the response.

Based on a message sent to the Growing Object-Oriented Software, Guided by Tests discussion group.

Copyright © 2010 Nat Pryce. Posted 2010-07-27. Share it.