Us software developers, we're used to living on the edge. We need to be constantly thinking about the "seams" where we can make our code testable, we have to expend considerable brain-fuel on "edge cases" in our algorithms, and, let's be honest, as far as society goes, we're generally typecast as being outliers there too ... :-)
But probably the most important edges are the ones we expose to our fellow
weirdos developers - our APIs.
A good API is one you can learn fast and completely. It should be lean and mean, exposing the minimum number of objects and methods to get the job done. It should use a consistent vocabulary and have a consistent approach (for example static void methods, "fluent" methods that return "this" for chaining, or conventional POJO/Manager interactions)
Some good examples:
- Google Guava's Lists, Iterables, Sets and Maps utility classes, which offer very consistent static methods for dealing with their namesake Collection classes
- Mockito and Hamcrest offer very readable and discoverable fluent interfaces: Mockito.when(mockThing.isReady()).thenReturn(false).thenReturn(true);
And some bad ones:
- I always find Commons Lang's StringUtils.isBlank() vs StringUtils.isEmpty() to be a bit confusing!
- JUnit's Assert.assertEquals(String, String, String) always requires a sneak peek at the javadoc to get the arguments right. They fixed it with the Assert.assertThat(String, T, Matcher<T>) style though!