Cost-reducing interfaces should be the focus
Posted by Tom Moertel Thu, 08 Dec 2005 22:35:00 GMT
I have been following with interest the debate about “humane” vs. “minimal” interfaces, sparked recently by Elliotte Rusty Harold’s response to Martin Fowler’s HumaneInterface post.
Harold writes:
Martin Fowler’s a really smart guy, and he’s pretty reliably right; but today he manages to get it 180° wrong. A 78 method List class is about three times as bad as a 25 method List class, not three times as good. A 12 method List class would be about twice as good. Simplicity is a virtue for both users and implementers. There’s simply no reason for 78 methods in a basic List class.
The problem with Harold’s argument is that he is using the wrong goodness metric. His metric is interface complexity when it ought to be overall cost.
Cost is what counts. If adding methods (or making any change, for that matter) reduces the overall cost of getting legitimate work done, it’s the right thing to do. That’s all there is to it.
Yes, adding methods to a library increases complexity and thus increases the cost of understanding and using the library. Adding methods to a library means asking users to make a small investment of their time and mental capacity in exchange for the promise of a later return – clarity and code savings. The duty of a library designer, then, is to make sure that this return is worthwhile, that the additions are useful enough and used frequently enough to pay for themselves.
In a later post, Harold implicitly acknowledges the does-it-pay-for-itself test when he lists some methods from Ruby’s Array class that he thinks are unjustified. He writes:
Do you really need any of [these methods] getting in your way? Possibly you need one or two of these methods; but how often, and how many?
The thing is, I use many of the methods he lists. Further, the ones I don’t use don’t seem to get in my way. In sum, those methods have paid me back far more than I have invested in them. Given this, why shouldn’t they be in the Array class?
I’m not saying that “humane” interfaces are better. Rather, I’m saying that focusing on “humane” vs. “minimal” is missing the forest for the trees.
Cost is what matters, so why shouldn’t it be the focus? Who cares if that focus leads us to a “humane” interface one time and a “minimal” interface another? With cost as our guide, we’ll always arrive at a good interface.
readers
I completely concur with forest / trees point (see my blog entry for more (linked above)). However, in terms of cost you’re missing a critical factor: context. It comes down to a simple question: Who defines the cost? In the general case, that’s a non-trivial problem. That’s why “creeping featuritis” is so deadly in the long term (look at the evolution of C++ and Java) and why design by committee results in completely wretched outcomes (witness all of the creation that the C++ “standardization” committee did).
John, thanks for your comment.
I don’t follow your logic here. Keeping the focus on cost ensures that context will be considered. How else do we arrive at some understanding of an interface’s cost if not through consideration of who will be affected by the interface and how those people will be affected?
That’s okay. We don’t need a perfect definition of cost to benefit from a cost-focused approach. Just thinking about cost provides benefits by itself.
Right now, too many library designers don’t think about cost. Instead, they apply higher design “principles” like DRY, YAGNI, or the 80/20 rule, or seek to make their interfaces minimal or humane, without due consideration of whether these principles or interface ideals make sense for the situation.
That’s why cost is important. It always makes sense, and it helps us put everything else in perspective.
Cheers.
Great point. Howerver the problem is how to determine the cost. It if often difficult, if not impossible, to get a bunch of users to try out your API and say ‘yes this is easy’ or ‘no this is too complex’ etc.
What techniques do you employ to achive the optimal solution?
I think Shalabh is mostly correct; phrased another way, the developer of a library may not be in a position to understand the costs. The more users the library has, the harder this problem becomes.
There are also different costs at stake:
...and many others as well. I think API designers use “principles” specifically as a hedge against these uncertainties: “I might be wrong in some of my assumptions, but at least by following this pattern I’m requiring someone else to be wrong along with me.” That seems like somewhat reasonable, if impure, logic.