Click here to Skip to main content
15,880,503 members
Articles / Programming Languages / Java / Java SE

A Quick Look at API Design

Rate me:
Please Sign up or sign in to vote.
4.73/5 (11 votes)
29 Apr 2009CPOL5 min read 28.5K   20   5
Suggestions to improve your approach to API design.

Introduction

Whether you know it or not, you are an API (Application Programmer Interface) designer. Every time you create a new class or enhance an existing one, the non-private methods and properties create, or add to, an API. So it makes sense, I think, to talk about what it takes to create a good API.

Unfortunately, there’s not enough room in a single article to cover all the topics involved in good API design. So, I’m going to briefly describe three of them, point you to some other resources, and ask you to contribute your ideas and questions on the topic.

Make it easy to use your API correctly

A good API should be easy to use correctly. That means, it should be easy to do the right thing, and difficult, if not impossible, to use it incorrectly.

I think it’s hard to argue against this point, but what does “easy to use correctly” really mean? As an example, let's compare how easy it is to determine whether a supplied date is Valentine’s Day using the Date class from the Java SDK and the DateTime class from the Joda Time library.

Here’s a first attempt using the java.util.Date class:

Java
public boolean isValentinesDay(java.util.Date date) {
    return((date.getMonth() == 2) && (date.getDay() == 14));
}

This looks pretty clean and wasn’t difficult to code. Unfortunately, it’s wrong. Let’s skip over the fact that the first methods you’d expect to use were deprecated years ago and should no longer be used, because there are more insidious problems. The test using getMonth() is wrong because Date uses a zero-based count for months, so we need to compare the result of getMonth() with 1 to test for February. The other problem is that getDay() doesn’t return the day of the month, it returns the day of the week, where Sunday = ‘0’ and Saturday = ‘6’. The correct method to call to retrieve the day of the month is getDate(), though it seems to me that calling getDate() on a Date objects should return itself.

Now, let’s see what it looks like using the Joda Time library:

Java
public boolean isValentinesDay(org.joda.time.DateTime date) {
    return((date.getMonthOfYear() == 2) && (date.getDayOfMonth() == 14));
}

This code also looks clean and easy to use. It’s involves a little more typing than the java.util.Date example, but this has the advantage of being correct. In Joda Time, the months go from 1 to 12, but if you want to make the month test even clearer, you can use DateTimeConstants.FEBRUARY instead of the magic number 2.

In this example, I’d say Joda Time does a much better job of making it easy to use the API correctly than the Java SDK does.

Make it hard to use your API incorrectly

What does it mean to prevent people from doing something wrong with the API? It depends on what the API is supposed to do.

For a Date class, it could mean not allowing the user to create an invalid date. So, when a user tries to set the day of the month to an invalid value (like February 30th, 2009), you have a choice: you can throw an exception, or do what the java.util.Date class does and roll the date to March 2nd.

While either solution keeps the user from setting an invalid date, silently fixing things can be dangerous because the user may not realize they’re doing anything wrong. Throwing a checked exception is sometimes seen as being “unfriendly”, but it is a way to explicitly tell the user that something is wrong so they have the opportunity to correct the problem before continuing.

Design your API with the user in mind

One of the best ways to determine what methods and properties your API should provide is to write some code that exercises the API. Note: You don’t have to write Unit Tests, though doing so is a dandy way to design your API and prove that it works at the same time.

As an example of why this is important, let me tell you about some legacy code I recently saw. The API included a method named getQueueCount() that accepts a string containing the name of a JMS queue and returns a count of the messages available in that queue. Most of the code inside the method is used to do a JNDI lookup and get an instance of the named queue, while just a few lines are used to get and return the message count.

The thing that makes this so bad is that in every place getQueueCount() is called, the calling class already has a reference to the queue, and has to call the getQueueName() method so it can get the string required by the getQueueCount() method.

If the API designer had written some client code, they would probably have noticed this pattern and could have refactored the getQueueCount() method to accept a reference to the queue. This would’ve made it easier on the client (no call to getQueueName()) and on the developer coding the getQueueCount() method, because they wouldn’t need to lookup the queue and retrieve an instance of it; they could just get the message count and return it.

Books, Articles, etc.

Now, it’s your turn

Do you have a hint, tip, suggestion, question, or warning concerning API design? If so, please add it to the comments so we can all benefit.

History

  • April 29th, 2009: Article submitted.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect LexisNexis
United States United States
Burk Hufnagel has been creating positive User Experiences since 1978 and is a Lead Software Architect at LexisNexis. Burk spends most of his life designing and crafting software, and has made a habit of creating practical solutions for difficult problems.
Recent achievements include co-authoring "97 Things Every Software Architect Should Know", speaking at JavaOne 2008, and being a speaker and mentor at the 2009 IT Architect Regional Conference in Atlanta, GA.

Comments and Discussions

 
Generalshine Pin
OmiD_Haghighatgoo1-Jul-10 10:27
OmiD_Haghighatgoo1-Jul-10 10:27 
GeneralPrefer Calendar Pin
CurtainDog7-May-09 19:16
CurtainDog7-May-09 19:16 
AnswerRe: Prefer Calendar Pin
BurkHufnagel8-May-09 3:17
BurkHufnagel8-May-09 3:17 
I totally agree with you about using Calendar. It certainly makes it easier to get things right.

The point in using Date in the example was to show that the JDK's Date class isn't consistent and sometimes things don't work the way you'd expect them too - which is a Bad Thing.

Thanks for the comment,
Burk
NewsClarification Pin
BurkHufnagel30-Apr-09 14:06
BurkHufnagel30-Apr-09 14:06 
GeneralRe: Clarification Pin
Andrew Rissing7-May-09 6:14
Andrew Rissing7-May-09 6:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.