I’m sure you’ve heard the term “law of leaky abstraction”, apparently put forth by Joel Spolsky (if you’re unfamiliar, please go read it – it’s worth your time). Lots of people have blogged about what leaks, what doesn’t leak, why things leak and so on.

To deal with this, people often are in search of creating a “cleaner” abstraction layer that doesn’t leak. And how many times have you seen an internal framework that took way too long to create – time spent refactoring to keep it “clean” by hiding the underlying system ? I think this is a big mistake…

Let’s face it, almost any framework today is built on top of a complex something else. And that something else is probably going to have quirks and limitations.   I think the trick to a clean framework isn’t hiding the quirks and limitations – it’s letting the user get to them and work around (or with) them in a layered manner.

Let me use an example (and I’m going to be light on technicalities here… this is just for illustrative purposes) – VB6 (remember that? ). A huge step away from raw C programming for windows. In VB every control (like a list box) that you drag onto a form had listbox functionality. You called methods and set properties, and it behaved list-boxy. Under the covers it was actually still a win32 window using built-in (to windows) functionality, nothing you couldn’t create with C. But VB abstracted away all of the cruft for things like adding a new item – instead of sending a LB_ADDSTRING message with SendDlgItemMessage using the id of the list and encoding the string to add in the LPARAM (whew!)… you just called ListBox.AddItem(“string”).

Great! But what if I want to do something with WM_CHARTOITEM? Or handle odd windows messages sent to to that listbox? Bzzt – no can do without bypassing VB’s listbox control altogether and creating it yourself, and possibly replacing the entire form. Now you basically need to go back and code stuff using a lower level framework (MFC/WTL/Win32/…). The abstraction leaks because I can’t do what I want (sending or handling some special message), and it sucks because I can’t do what I want with this framework at all.

Now along comes Windows Forms – we get an all new listbox. It also abstracts away things like creation, adding an item and all that while still using win32’s listbox. Great! But when I want to send or handle some special win32 message the abstraction allows me to – it may not help a whole lot, but it certainly makes it possible if not simple. This abstraction still leaks because I still can’t do what I want without sending or handling some special message, but it doesn’t suck because I can use the framework and still deal with the underlying system. The abstraction feels “cleaner” because it doesn’t hide the leaks.

For this reason, I love the design of some of WCF - it feels great because it allows you to deal with the underlying system at various layers of abstraction. You choose – highly abstracted, some abstraction, or almost none. If you find the framework is hindering you, you can just jump down a level without abandoning the framework and all its existing code. This abstraction feels even cleaner even though it goes to more lengths to show you the underlying system behind the façade.

So above we have three levels of abstractions letting water into our boat:

  1. VB – There are no leaks, I see no leaks. (gurgle)
  2. Windows Forms – Yes, there’s leaks. (yawn) - If you don’t like them here’s a bucket – bail ‘em out yourself.
  3. WCF – There are no leaks, we’re in a swimming pool – enjoy the water. Here’s a floating chair

Which would you choose? And what’s my point? Embrace the leaks. Don’t hide them in your framework to make it cleaner! Instead, find a way to expose them all, within your framework. Get wet.