Rule 7. Eliminate Failure Cases

That title seems optimistic, doesn’t it? What does it even mean?

Some failure cases are unavoidable, right? If I try to open a file, that file might not exist, or it might be locked by some other user. No interface-design cleverness can avoid the possibility of failing to open the file. So that can’t be it. This must be more about eliminating the failures that actually are avoidable, not intrinsic to file operations—perhaps usage mistakes, like writing to a file after you’ve closed the handle to that file, or calling methods on an object before you’ve fully initialized it.

Maybe I could design systems that make it impossible to make usage mistakes, but that doesn’t sound easy. And it isn’t. It’s pretty hard to design a system that’s impossible to misuse. If you expose a feature to users, they’ll find a bizarre way to use it that eventually causes everything to explode, like building a functioning 8-bit processor entirely out of Minecraft blocks.1

And if you expose a feature to other programmers on your team—they will misuse it. The misuse might be intentional, a desperate attempt to get something working—say, closing a file handle after calling the filesystem shutdown routine because that’s the only way to avoid an unwanted callback. More likely it will be entirely unintentional, a misinterpretation of how your interface expects to be called.

The key question to ask yourself about your design is: “How hard am I making it for users of this feature ...

Get The Rules of Programming now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.