June 08, 2005
Interfaces suck for public APIs
While coding against interfaces often makes for better design, publishing interfaces as part of a public API might put you in a world of hurt.
Imagine your application offered some kind of plugin architecture. You publish an interface Plugin which other people can implement and then use with the rest of your code. Your application becomes a wild success, with people all over the planet contributing plugins for fun and profit. All is great... until you think about writing version 1.5.
Suddenly you need every Plugin to implement an additional method getURI() and quickly realize there is no way of doing that without breaking the hundreds of contributed plugins in existence. Had you chosen to make Plugin an abstract class instead of an interface, you could just add a default implementation for getURI() that would, say, return the fully qualified class name as URI. But as you can neither replace an interface with a class without breaking binary compatibility, you're officially fucked.
When I was googling for this problem I found an excellent set of presentation slides from Jim des Rivières called Platform Quality APIs (260 KB PPT). It contains a lot of valuable advice for anyone wanting to write an API to stand the test of time. Since the presentation is unfortunately only available in Powerpoint format, let me paste in a slide called Use Java classes and interfaces wisely:
- API interfaces that clients do not implement are useful
- Excellent way to insulate client from implementation internals
- Allows there to be multiple implementations
- Adding methods in future is non-breaking
- API interfaces that clients may implement are inflexible
- Adding method breaks binary compatibility
- Abstract classes work better for this
- API classes that clients do not subclass are useful
- Use factory methods and hide constructors
- API classes that clients may subclass are useful, but difficult
- API frameworks are notoriously hard to specify
- Needs additional contracts for subclassers
Did I just write a "considered harmful" article? I never wanted to be like that.
Comments
Erich Gamma also raises this point in an interview with Bill Venners: http://www.artima.com/lejava/articles/designprinciples.html
Posted by Hendrik Swanepoel (#)
Thanks for the link. I enjoyed the whole series of Gamma interviews!
Good point about the Interfaces... I never thought about that. Could the Abstract Skeleton pattern (I think that's what it's called) help here?
I remember reading about this in Effective Java, and it's certainly not an obscure pattern... something along the lines of Providing both a public Interface and an Abstract skeleton implementation a la java.awt.MouseAdapter... Then users of the api could just extend the abstract class...
Wait a minute... I just proved your point, since they'd still be subclassing the Abstract class and not implementing the Interface directly. oh well.
Post a comment
Thanks for signing in, . Now you can comment. (sign out)
(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)![[TypeKey Profile Page]](http://www.netalive.org/swsu/nav-commenters.gif)