User Interface Principles in API Design
Elliotte Rusty Harold
elharo@metalab.unc.edu
http://www.cafeaulait.org/

Programmers Are People Too
Eat Like Humans
Sleep Like Humans
Mate Like Humans
Think Like Humans

User Interface Design is a Science
Based on hypothesis, observation and experiment
Well-proven, well-tested theories

Fundamental Principles
Consistency is next to godliness
Simpler is better
Visible complexity is bad
Smaller equals easier to use

Libraries vs. Applications
Applications are monolithic
Only other programmers on the same team use an application’s API
Libraries can make very limited assumptions about how, when, where, and why API will be invoked
Boundary is fuzzy

Remember the People
Why You Need An API
Who Uses the API
Who Designs the API

What to put in an API
Write sample programs first
80/20 rule
Maximal APIs
When in doubt, leave it out!

Dependencies
Platform version
Library dependencies
Built-in vs. 3rd party libraries

Data Encapsulation
Public vs. Published
Fields are private
Methods are mostly private
Methods are atomic
Constructors and destructors
Communicating with the user

Constraints
APIs must enforce domain validity
Preconditions
Postconditions
Class invariants
System invariants

Error handling
Specify what happens on bad input as well as good
Important for security
No undefined behavior

Naming Conventions
Review naming conventions
Use standard terminology
Do not abbreviate
Use domain specific vocabulary
Consistent terminology: always use the same word for the same idea
e.g. add vs. append
Do not use two words for one idea

Avoid Complexity
Prefer classes to interfaces
Prefer constructors to factory methods
Avoid excessive abstraction

Inheritance
Prefer finality
Factories and interfaces
The proper use of protected

Plays well with others (Java):
Serializable
Cloneable(*)
Comparable
equals()
hashCode()
toString()
Exception handling
Thread safety

Plays well with others (.NET):
Equals() / GetHashCode()
ToString()
IEquatable<T> / IComparable<T>
“Collection” suffix for IEnumerable classes
Icloneable*
Override ==, etc. for value types (only)
No pointer arguments to public methods
Don’t throw exceptions from overloaded operators and implicit casts

Documentation
Specification
Quick Start
Tutorials
Example code
API Documentation
Per method checklist

Conformance Testing
Specifications
Test Suites
Implementation dependent behavior
Implementation dependent extensions

Maintenance
Planning for the future
Forwards compatibility
Backwards compatibility
Unexpected  limits
Deprecation
Breaking compatibility
Interfaces vs. classes

The Last Concern (Performance)
Speed
Size
Energy

Case Study: DOM vs. JDOM
Case Study: BoxLayout vs. GridBagLayout
Further Reading
Effective Java: Joshua Bloch
Effective C#: Bill Wagner
Framework Design Guidelines: Krzysztof Cwalina, Brad Abrams
Tog on Interface: Bruce Tognazzini
GUI Bloopers: Jeff Johnson