Designing an API is an art and a science. Many intelligent people have failed. Those who succeed do so by keeping in view the main goal of an API: to annoy the hell out of developers.
My brothers and sisters, to honor that noble-ish pursuit we gather together to enumerate (see what I did there) the Seven Deadly Annoyances of API design. I never thought I’d write a listicle, but at least it has an erudite religious reference in the title.
First, a couple rules: Weâ€™re talking about successful, working APIs here. So things like â€œit doesnâ€™t workâ€ or â€œit opens a massive security holeâ€ donâ€™t count as annoyances. Don’t take the word “deadly” literally. And APIs that no one uses are not qualified. No, failed APIs are not annoying, just bad. Here we discuss just the minor things. The minor, hair-pulling, keyboard-smashing, Urban-Dictionary-quoting annoyances we all know and despise.
Many of the examples come from Android, because that’s who most recently has the pleasure of annoying me, but I donâ€™t mean to pick on them. They have no monopoly on these sins.
Annoyance the first – trsnss
Yes, name-ification of things is hard. Still, common sense could go a long way. You gotta hand it to the Unix folks for their heroic efforts to save a keystroke – why say dupe when we can save that valuable E and say dup?
Number two is related:
Annoyance the second – makingNamesMuchTooLongToBePractical
Apple, in contrast, gives us gems like
Vexation number three – Using synonyms
Oh, Android, Iâ€™m looking at you.
Apparently thereâ€™s a difference between a â€œBlankActivityâ€ and an â€œEmptyActivity.â€ Whatâ€™s the difference? I once knew, but now Iâ€™m drawing an empty – I mean a blank.
Android gives us tool bars, which at some point got renamed app bars, also known as action bars, giving us lovely code like:
Â Â Â // Set the toolbar as my app bar Â Â Â setSupportActionBar(myToolbar);
To abbreviate or not to abbreviate. Thatâ€™s apparently not the question at the Googleplex. Por que no los dos? Cross reference getExternalDirectory and getExternalFilesDir. These return two different locations, by the way, because sometimes in a directory you want to store files, and sometimes you want to storeâ€¦ I dunno, something else.
Whatâ€™s the difference between a tap and a touch? I have no idea (at least not on a phone), and neither does the Android design team, who also sometimes calls it a click.
Hey, what version are you running? Oh, it’s KitKat. Or is it 4.1? No, maybe it’s SDK version 19… Oh wait, those all mean the same thing. Good luck keeping them straight.
And a final Android example. Want to make a project asset available by URL? Simply put it in the /assets/ directory in your source tree and construct a URL starting with â€œfile:///android_asset/â€. Yep, one is plural, one is singular. One has android_ in front, one doesn’t. Why? Because theyâ€™re Google and they can do whatever the hell they want, thatâ€™s why. What are you gonna do, use FirefoxOS?
Annoyance the fourth – Poor (or absence of) documentation
Speaking of asset URLs, you wonâ€™t find out about them by reading the documentation, aside from an offhand mention of it on the WebSettings.setAllowFileAccess method – a method which has zero affect on whether you can access files this way. Yes indeed, the old semi-documented feature.
Then thereâ€™s the Context class. It’s the Kardashian of classes: no one is quite sure what it does, but it’s everywhere you look. No one knows why, but you need it for almost all API calls. So thereâ€™s that.
Want to add a toolbar/action bar/app bar to your Activity? Hereâ€™s how you do it using the backward compatibility library. What if you donâ€™t need backward compatibility? Surely thereâ€™s a way to do that with the built in classes? Probably, but you wonâ€™t find that in the official documentation.
And speaking of backward compatibilityâ€¦
Annoyance the 5.1beta3 – Version incompatibility
If youâ€™ve developed for Android, you know. Oh, you know all right. Iâ€¦ I canâ€™t even write about this. The memories are too raw. Just.. you know.
WHY DOES IT WORK ON KITKAT BUT NOT MARSHMALLOW OR JELLYBEAN?!?!?!?!?!?
Annoyance the 6 – Overcomplimification (easy things made hard!)
Ahh, Fragments, how I love to hate you. Hereâ€™s a real diagram from Android documentation:
But worse than Fragments are Notifications. Check the Android documentation for the section â€œCreating a Simple Notification.â€ Just in case they werenâ€™t clear how simple it is, they make sure to repeat the word in the first sentence: â€œThe following snippet illustrates a simple notification.â€ Care to see this oh-so-simple code snippet?
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!"); // Creates an explicit intent for an Activity in your app Intent resultIntent = new Intent(this, ResultActivity.class); // The stack builder object will contain an artificial back stack for the // started Activity. // This ensures that navigating backward from the Activity leads out of // your application to the Home screen. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); // Adds the back stack for the Intent (but not the Intent itself) stackBuilder.addParentStack(ResultActivity.class); // Adds the Intent that starts the Activity to the top of the stack stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT ); mBuilder.setContentIntent(resultPendingIntent); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // mId allows you to update the notification later on. mNotificationManager.notify(mId, mBuilder.build());
Oh dear, Iâ€™m overwhelmed with the beauteous simplitude!
Just to rub it in, the Android documentationalists follow this up with â€œThat’s it. Your user has now been notified.â€ Oh, thatâ€™s it! Wow, and here I thought there would be some code involved, but now that youâ€™ve shown me this crystal clear 27-lines of beauty, I feel relievificated. And donâ€™t forget to import the three class you need. Oh yeah, and if you want backwards compatibilitude, itâ€™s a whole different set of classes, plus you upgrom your gradle file and and do something else I mean who cares itâ€™s stupid i give up i quit ill be a bartender.
Oh, and donâ€™t forget to also copy-paste these 30 lines of XML into a completely different file.
Speaking of which, the final and seventh deadly annoyance of API design is…