The "No Special Case" Pattern
Very often I'll write (or use) APIs that look like this (translate accordingly for Ruby / Javascript code)
Thing findOneThing(Key key);
// if nothing is found, throw an Exception or return null
Collection findManyThings(Collection keyList);
// if nothing is found, return null
All well and good? I'd known the textbook-bullet-points for this, but for the longest time, I didn't realize how much tax I'm paying subconsciously.. and just how many APIs are ignoring this wisdom:
Nulls are awkward things in object-oriented programs because they defeat polymorphism. link »Instead of returning null, or some odd value, return a Special Case that has the same interface as what the caller expects. link »Not all language can do this easily link »
- from P of EAA: Special Case via sharedcopy.com
Finding yourself having to check for null return values? That's not "the way it is", that's tax.
Ruby helps a bit by making "nil" an object, paving way for the much loved duck-typing. Whereas some languages settle for dead bodies equivalent nulls. Especially in these languages, having to "return a empty object with the same interface" is a real chore. Person? EmptyPerson. Record? EmptyRecord.. ad infinitum
Still, a language can really only help so much. And it is up to the library authors (i.e. you) to put this wisdom into practice. "Practice?". Now comes the funny part.
When talking about "design patterns", usually images of "Enterprise", "UML", "Configuration files" start appearing in my mind. So I find it ironic that the best real example of this pattern comes from the lowly-regarded (by many "real" engineers) realm of Javascript. Its called jQuery.
In fact, jQuery takes it even further by simplifying Martin Fowler's pattern into a single practical use-case: Returning 1 object is equivalent to returning a List containing 1 object. By always returning a List (which can be empty, duh), it has even avoided the need to conjure special "null object with equivalent interface"! And most importantly, "practical" because all languages can do empty list.
Its amazing how simple your train of thought (and code!) becomes when everything is a list (tiny voice: uh.. Lispers knew that since before you were born... blah blah). There's nothing to decide, you always loop through the return value. 0 time? 1 time? N times? Imagine all those other idioms & body of code, now becoming unnecessary... its applying liposuction for your source code!
I don't suppose its too far fetched to apply some jQuery-ism to ActiveRecord API is it?
Update: Changed title from "Unspecial Case" to the "No Special Case", which is more correct.