Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

When designing an API, consistency often aids usability. However, sometimes they conflict where an extra API feature can be added to streamline a common case. It seems like there's somewhat of a divide over what to do here. Some designs (the Java standard library come to mind) favor consistency even if it makes common cases more verbose. Others (the Python standard library comes to mind) favor usability even if it means treating the common case as "special" to make it easier.

What is your opinion on how consistency and usability should be balanced?

share|improve this question

closed as too broad by durron597, MichaelT, gnat, Ixrec, GlenH7 Sep 5 '15 at 13:12

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

I guess I'm lucky as I never had to make such a choice as the chosen shared pattern is usually already the most friendly.

However if I'd have to choose, I'd go with consistency: that makes things easier to debug and clearer communication within the team.

I'd even go as far as to say that a consistent API is part of what makes it usable.

share|improve this answer

I would be try to be both consistent and usable.

If the consistency gets in the way of usability (where an API can be streamlined as you mentioned), then offer a new class, function, or wrapper library that does just that. Just make sure in commenting/documenting the code that it is obvious how each function is related.

It's like overloading constructors. Sure the one with 3 parameters is most consistent and flexible but maybe the constructor with only one parameter is used most often in your application.

Then your library will be both flexible (as Jeremy pointed out) and usable as you would like it to be for the normal use case.

share|improve this answer

I would go with consistency myself. Your clients can always write wrappers to your library to make them easier to use or remove duplication.

You could also provide another API next to the main one that wraps the main API for them so they can use it for the most common cases.

share|improve this answer

I find that often favouring usability reduces the flexibility of that part of the API, because now it's tailored to the special case.

share|improve this answer

There are more design dimensions. Being pedantic (& opinionated):

  • Consistent: similar operations appear similar across interfaces
  • Usable: API solves majority of user problems with little added boilerplate
  • Simple: operations express single intent (likely they can be usefully reassembled by client)
  • Encapsulated: API exposes minimal interface (maximizing what implementation can change without breaking callers)

The design choice should depend on how your API interacts with the rest of the system, "level" (low/high) of your API, how well defined the problem is, etc.

If you're designing something that looks very much like existing API's--especially system API's--consistency is probably more important than usability. As others have said, usability could be layered on top as a separate API. That higher-level API should probably be designed for usability.

Low-level APIs should focus on simplicity since they will potentially be used by lots of higher level APIs. Being able to combine the calls in different ways is important.

Encapsulation is especially important if the problem isn't well explored. Exposing a lot of an experimental interface is asking to have lots of broken client code (or having to maintain legacy code) if you have to change the design. In this case it can make sense to ignore simplicity/consistency and instead only expose as few functions as possible.

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.