views:

111

answers:

4

When designing the public API of a generic library, how much of the low-level stuff that's used internally should be exposed? On the one hand, users should not depend too heavily on implementation details, and too many low-level functions/classes might clutter the API. Therefore, the knee-jerk response might be "none". On the other hand, some of the low-level functionality might be useful to people, and exposing more of it can prevent abstraction inversion (the re-implementing of low-level constructs on top of high-level constructs).

Furthermore, exposing more low-level details could provide performance shortcuts. For example, let's say you have a function to find the median of an array. The principle of least surprise says that you should duplicate the array so that users of your API don't have to care that its implementation involves the side effect of reordering elements. Should you, in this case, note that median() costs a memory allocation and provide another function that bypasses the allocation, but will arbitrarily reorder the user's input?

What are some general guidelines for how much of this kind of detail to expose?

+1  A: 

As little as is possible.

The more details you expose, the more likely a change will break a consumer.

Mitch Wheat
+2  A: 

Your API shouldn't allow callers to "break" anything by mucking up the state of the internals (e.g. reordering collections, etc.). To solve that problem, your exposed interfaces should be read only when necessary.


With respect to complexity, I lean far in the direction of simple, basic methods. I try very hard not to over-engineer anything with what I think will be needed down the road.

Write to today's requirements (maybe tomorrow's), but not beyond. You can always extend in the future. It's much harder to just drop things that you can't maintain anymore.

Michael Haren
+1  A: 

The unix way of doing it is to provide mechanisms, not policies. Just provide the right tools to do things (say, a knife), but try not to anticipate how they are going to be used (to peel apples or to sharpen pencils).

PolyThinker
Can you elaborate on this? I really don't quite understand what you're saying.
dsimcha
A: 

One way I've heard it expressed: Expose the what, but not the how.

The goal is to provide a useful and rich library for clients to use, without making them dependent of the library's internals. You want to be able to change the internals, without breaking the callers (as someone else already noted).

Writing a good API involves a certain amount of artful brinkmanship.

Brian Clapper