Monday, November 19, 2018

Needs- and Capabilities-Oriented Interfaces

A mugger shouts "Gimme your wallet!" The victim replies "Sorry. I only carry a money-clip."

Among the many and varied ways to categorize interfaces is this one: needs-oriented and capabilities-oriented interfaces.

A needs-oriented interface is one that allows a client to ask for what they want. A real-world example of a needs-oriented interface is the mobile app for Lyft or Uber. You tell it where you want to go, negotiate and agree to terms such as cost and wait-time, and go there.

A capabilities-oriented interface is on that allows a client to ask for work to be done on its behalf. A real-world example of a capabilities-oriented interface a classic offset-barrel smoker. You control how much fire you have but adding wood, adjusting intake and exhaust vents, and leaving doors/hoods open or closed.

It's not that one is good and one is bad. They just serve different purposes.

An offset barrel smoker is part of an American tradition. There's an enormous amount of inertia around how it works. It's also very versatile. There are a lot of things you can do with an offset barrel smoker. Basically, an offset barrel smoker is part of the American Barbecue framework - it can be used in a lot of ways and it is okay - even expected - that it will not change.

Consider your programming language of choice. Can you think of a type that meets those requirements? It seems like the built-in collection types usually fit the bill.

Capabilities-oriented interfaces are really good for frameworks but they fall down when the fundamental assumption of a framework - mostly slow, primarily additive change - is violated.

Needs-oriented interfaces tend to withstand change a lot more readily. This is because a need doesn't usually transform into another need. It happens, but not often. Typically, a need either stays the same or goes away entirely.

Implementation details, on the other hand, can change on a daily basis.

What if the ride-sharing interfaces were focused on how you would arrange a ride rather than getting you where you want to go?

The moment something about fulfilling your need changed, the ride-sharing apps would have to change the interface to which you were coupled. If they brokered a sequence of text messages between you and potential drivers and suddenly text messaging was out of vogue, they'd have to change the interface and retrain a bunch of customers. If they get better technology, like driverless cars or single-passenger drones, they'd have to change the interface again.

Yet, by allowing you to express your need, the ride-sharing applications let themselves free to experiment with different processes and different means of conveyance.

The strength of a needs-oriented interface is that it will probably not change unless the associated need changes, which is rare. The weakness is that cannot typically be used by a wide audience in a large variety of ways.

If you are working on the .NET Core team or contributing to a broad-audience, low-level open source library, a capabilities-oriented interface might be the right choice. Otherwise, you probably want to focus on the needs being fulfilled when crafting a class, service, or application interface.