Usable APIs: Dependency Injection, Failure Strategies, Duck Typing and REST
|
|
In a previous blog entry, I pointed out the deficiency of Java function (aka method) call contruct in supporting API usability. I mentioned the Half-Bean pattern as a good way to compensate in an OO fashion. But later in the day I realized that the Dependency Injection pattern also achieves similar objectives. One complaint about Java apis being difficult is because most are designed for flexibility there are just to many places and ways to do configuration. To simplify this for developers you need to consolidate those configurations into a single place. The Dependency Injection addresses this need head on and in addition make configuration seperable from the context in which its used. Not only is the complexity of configuration addressed, but the complexity is displaced away from the main line of code.
However, I stumbled upon Bruce Eckel's comments about the usability benefits of duck typing. Now, I've talked about duck typing elsewhere, but I haven't thought about it in the context of API usability. Bruce Eckel implies that this is one of the primary reason why people feel more productive using Python over Java. Juha Komulainen argues that with judicious use of JDK 1.5 features, you can approximate the same terseness using Java, however he points out that it is wrong but works only in the context of a scripting enviroment.
One underrated point about scripting is that they can sometimes be extremely robust. Their robustness comes from the fact that the interpreter is run and terminatde on a per script basis. So a script writer can forget to do so many things like failing to close files. As the interpreter is terminated, the operating system takes care of all the dirty work of cleaning up (sounds like garbage collection doesn't it?). Have you noticed that CGI based programs seem to be extremely robust? The robustness comes from the robustness of the process management of the operating system. You can emulate it like in a Windows 3.1 enviroment and compromise stability, or you can build it in up front like in Unix. In fact, paraodoxically to achieve robustness, your software should be "crash only" software.
Usable APIs clean up for themselves, that's why one of the strengths of Spring is that it has this Template mechanism for database access that has a built in strategy for handling exception handling. This spares the developer from devoting as much concern with this aspect. Yet another usability technique, provide robust ready made strategies to handle failure.
I digress, I wanted to talk about how duck typing improves usability. In an earlier piece about programming with adaptors, I pointed out that a lot of menial work in programming covers transformation from one type to another. Well, if you let the runtime system carry this load a bit more, then that would definitely save from typing (i.e. keystrokes, pun intended). In short, let introspection do a lot of the dirty work, I mean, hasn't those Jakarta BeanUtils been such a boon to productivity?
Interesting enough, uniform interfaces make programming by adaptors even more powerful. Have you ever realized how Unix command line programs with their piping semantics have been so useful. That's because the interfaces are so uniform, being uniform makes them much easier to compose. Just look again at the often quoted lego block analogy, look at the shape, not the concept. The lego blocks have uniform interfaces, they don't have a multitude of different kinds of interfaces, it's just one kind! Different shapes but the same interface.
Now, most surprising of all, this leads me back full circle to the original article, "implicit invocation". See, implicit invocation works because you have uniform interfaces, so not only do you get the benefits of reducing sequence dependencies, you gain the benefits of composability.
In summary, we've picked up a couple more Usability techniques:
- Support Configuration using Dependency Injection
- Provide ready made Failure Strategies
- Let introspection do the thinking for you
- Provide uniform interfaces

