The Golden Rule of API Design

From WikiContent

Revision as of 20:39, 6 July 2009 by Mfeathers (Talk | contribs)
Jump to: navigation, search

API design is tough, especially in the large. If you are designing an API which is going to have hundreds or thousands of users, you have to think about how you might change it in the future and whether your changes might break client code. You aren't going to be able to refactor your AI freely over time, so there are some decisions that you have to get right, because right or wrong you are going to have to live with their consequences for a long while. Above all, you have to protect your API. If one of your API classes uses one of its own methods internally, you have to remember that a user could subclass your class and override it, and that could be disastrous. You wouldn't be able to change that method because some of your users have given it a different meaning. Your future internal implementation choices are at the mercy of your users.

API developers solve this problem in various ways, but the easiest way is to lock down the API. If you are working in Java you might be tempted to make most of your classes and methods final. In C#, you might make your classes and methods sealed. Regardless of the language you are using, you might be tempted to present your API through a singleton or use static factory methods so that you can guard it from people who might override behavior and use your code in ways which may constrain your choices later. This all seems reasonable, but is it really?

Over the past decade, we've gradually realized that unit testing is an extremely important part of practice, but the lesson has not completely permeated the industry. The evidence is all around us. Take an arbitrary class untested class which uses a third-party API and try to write unit tests for it. Most of the time, you'll run into trouble. You'll find that the code using the API is stuck to it like glue. There's no way to impersonate the API class so that you can sense your code's interactions with it, or supply return values for testing. Over time, this will get better, but only if API developers start to see testing as a real use case.

Personal tools