People think a lot about abstractions and how to design them well. Here’s one feature I’ve recently been noticing about well-designed abstractions: they should have simple, flexible and well-integrated escape hatches.
Inevitably, when you use an abstraction layer to accomplish a task, you’re going to run into cases where you can’t express what you want using the abstraction layer, and you have to “drop down” to a lower-level tool. (For example, you might be using Python and realize that you have a particular loop that’s really slow and needs to be rewritten in C.) Abstraction layers try to pretend they can do everything for you, but that’s never true, so it’s vital that they make the process as painless as possible.
There are three main things that such an escape hatch should be:
Simplicity. It should be easy to drop down to the lower abstraction level.
Flexibility. One you’re there, you should be able to do whatever you want.
Well-integrated. You shouldn’t have to use the escape hatch for any longer than absolutely necessary. After you’ve dropped to lower-level tools, it should be easy to go back up to the abstraction layer.
Specific examples to come when I’m not about to board a flight…