Tuesday, December 06, 2005

Form Follows Function

For the past several weeks, I have been working on an API at work. The first step was to design the API and have it reviewed by other software architects. I was surprised by how much time we spent debating the mere form of the API. For example, we argued a lot about whether to use interfaces or classes for value objects, but comparatively little time discussing the function of the API. I am not saying the interfaces vs. classes debate is not important, but often the argument was, "By convention, all value objects must be defined as interfaces (or classes)." In other words, it was a case of form for form's sake. The argument was not grounded in the function of the API.

Now that I have moved from design to implementation, I am noticing another kind of tension. As developers begin to use the emerging API, they make enhancement requests. Often these requests are to add a method that is outside the scope of the API, or worse, to make an existing method do some additional work that isn't obvious from the method definition. As an example, I've had several requests to make methods aware of the User Interface (UI) context, but this is an API for accessing data and metadata. None of its implementations should introduce side-effects in the UI unless all of them can guarantee the same behavior. I think it is important to keep the API contract as simple as possible, so I generally decline such requests.

It strikes me the answer to both kinds of debates is the same: "Form follows function." This phrase first gained currency in the discipline of building design. The late 19th century architect, Louis Sullivan, and his disciple, Frank Lloyd Wright, were its most famous proponents. The phrase is sometimes misinterpreted as a statement of precedence. In other words, it is interpreted as, "function precedes form," but that's not really the idea. Rather, Sullivan and Wright were reacting against the conventions of the day. They thought it was silly to build Renaissance train stations, Greek Classical post offices, and English Tudor homes. There were against ornamentation for ornamentation's sake. As Wright said, "Form and function should be one, joined in a spiritual union."

"Form follows function" has been applied to lots of other design activities besides building design. I actually haven't heard it used in reference to the design of an API, but I think it makes sense. It carries with it two important ideas. When designing an API, you should:
  1. Resist unecessary ornamentation. Some conventions are certainly of universal importance, but others should be applied in only some circumstances and some are mere fads. Each convention should be tested against the function of the API. Does it really make sense in this context?
  2. Make each method as explicit as possible. To improve the usability of your API, give each method a descriptive name and make it do what it says -- no more, no less. Avoid the temptation to have methods cause side-effect in other parts of the system. This is particularily important for APIs that will have multiple implementations.
Next time someone tells me I must always use interfaces for value objects or I must follow some other such convention, I'm going to say I heard differently from a famous architect. "Form follows function." I heard it from Frank Lloyd Wright.


Pete said...

Great post Dave. You deserve a wider audience for your insightful posts.

Bob said...

Don't let 'em get you down Dave. Spending more time discussing the form of the API rather than its function is a clear sign of Architecture Astronaut syndrome.