designing tools for programmers, including languages, APIs, and compilers, is a human factors problem
It’s a huge leap to recognize this reality. Graham Glass, the creator of GLUE and founder of The Mind Electric (TME), blogs:
TME has a philosophy for designing software that I would like to share. The starting point for anything we build is the “user experience”. Before we even think about stuff like standards compliance or implementation, we focus on what a user of our software/APIs will experience. Simplicity is the %231 objective. Only when this has been accomplished (at least on paper) do we talk about implementation details. Only when this has been simplified do we think about standards compliance. Even though this might sound backwards, it always seems to work out well in the end.
Developing webservices with GLUE is an extremely pleasant experience (you can see a viewlet of it in action here). Thus, simplicity concerns override all other concerns, it does remind me of the “worse is better” philosophy to language design.
We can learn alot by studying the API’s of GLUE, however has anyone written any tips on how to do this? I do recall a couple, Ken Arnold says:
Any mistakes you can’t make impossible, you want to catch. In other words, first design such that improper things can’t even be written or expressed. They are impossible to do. Errors you can’t make impossible, you want to catch right away. So as soon as a user makes a mistake he or she is told.
Don’t give people a method that does something error-prone. Give them the method that allows them to do the subset that is not error-prone. Suppose you have a file object on which you can call open and close. You can only close an open file. You shouldn’t be able to call close on the file object, because it may not be open. The open method should return something on which you can invoke close.
The first suggest seems to allude to the checked exception handling found in Java. At this moment there’s plenty debate regarding that topic. The second seems to allude to the Curried Object pattern, that is encapsulate complex interactions in an object.
Kartzen Lentzsch, of JGoodies fame, writes about his reasoning behind his new Layout API:
SpringLayout needs more code than the FormLayout to express simple but frequently used form design. From my perspecitive, the main problem with SpringLayout is, that the layout specification language (Java code) doesn?t represent the human mental layout model well. You can hardly see the layout by just looking at the panel building code. FormLayout?s layout specification language has been designed to express how many people think and talk about layout. How many lines of code do you need to build the form in Example 3 with the SpringLayout?
FormLayout favors an expressive layout specification over extensibility. It has been designed to be powerful and flexible enough to layout almost every panel that I?ve designed during the last decade. It covers all panels in the JGoodies tools and seems to be able to layout all panels in large apps like the Eclipse JDT and the NetBeans IDE. And so, I doubt that there?s a need to extend the FormLayout ? at least it isn?t urgent.
The first insight recommends that API’s be defined to reflect the mental model of the programmer. The second is another suggestion, provide expressibility over extensibility.
That’s four rules of thumb on how to design your API’s, are there more? I am sure that most programmers are completely unaware of these, in particular Sun’s programmers who continually create API’s that favor complexity and extensibility over simplicity and expressibility. It’s possibly a good exercise to collect all the “hall of shame” APIs we can find in the standard libraries.
:: Comments at Artima ::