Pretty banner! :)

Make the Smart Choice So That Your User Doesn’t Have To (3/3)

This is final part of a three part series. You may want to check out part 1 and part 2.

API Design

As a Flash game developer, you’ll find yourself interacting with all sorts of APIs designed and implemented by third parties. Because most libraries aspire to being popular, they generally strive to include as many features as possible, and support all manner of possible interactions with their API. Few API designers take the time to consider what primary motivation drives the user of their API. Programmers are elitist snobs. Generally speaking, the only time we are willing to consider dirtying our pretty code with someone else’s, is if its going to save us time (and therefore money).

When I began this article, I intended to point to some specific APIs that I use regularly whose designers failed to take this into account. Being that I still use these APIs on a regular basis, I decided it was best not to ruffle any feathers and instead just talk about how to apply this strategy instead. For fun, though, I’ll post some DirectX code here that I’ve always thought was a particularly heinous trespasser in this regard.


void initInput(HINSTANCE hInstance, HWND hWnd)
{
    DirectInput8Create(hInstance,
                       DIRECTINPUT_VERSION,
                       IID_IDirectInput8,
                       (void**)&din,
                       NULL);

    din->CreateDevice(GUID_SysKeyboard,
                      &dinkeyboard,
                      NULL);

    dinkeyboard->SetDataFormat(&c_dfDIKeyboard);

    dinkeyboard->SetCooperativeLevel(hWnd,
                                     DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);

      return;
}

Note: I’m not saying this code is necessarily bad. Instead I’m trying to illustrate that there really is no good reason to require an application to specify much more than a single line of code that requests an initialized keyboard object. Sure I might sometimes care about all that other crap, but why make me bother with it every time I want keyboard controls? Also, Hungarian notation! So much fun!

A reasonable rule of thumb when approaching your API’s design is this: If I am trying to accomplish a single task, give me an opportunity to do that with one action, or at most two if reasonable technical restraints require it (like an asynchronous interaction). As soon as you want me to create 15 different interrelated objects that all require special customization, listeners and handlers, just to accomplish a single task, you’ve just eaten into the main reason I decided to use your API in the first place, and that is to get where I want to go quicker.

Because flexibility is so important to most API designs, I don’t want to suggest that we can get away with simple APIs. Instead, I want to suggest that the API assume that the defaults are sufficient unless the client code specifies otherwise.

To further illustrate the point, here are some basic examples of where we might want to make assumptions to simplify our API:

  1. Assume that I want the mass of my physics shape to be proportional to its size, unless I say otherwise.
  2. Assume that I want to connect using the most efficient protocol possible, unless I say otherwise.
  3. Assume that I don’t care about being notified about the completion of an event, unless I say otherwise.
  4. Assume I don’t care about hidden files, unless I say otherwise.
  5. Assume I want you to save the file when I write to it, unless I say otherwise.
  6. Assume that I’d rather use the file system to manage my assets than some convoluted proprietary library, unless I say otherwise.

What I’m trying to get at here, is that by making assumptions and providing smart default choices for our API, we eliminate the number of things the user needs to learn (and just as often relearn) when working with our code. We are qualified to make the smart choice for our user because we know what we’re doing, which is why we built this API to begin with. Sure, the user is entitled to override our default choices with something that’s more specifically tuned to his application. But our defaults are invisible to the user. We can potentially eliminate one more thing the user needs to learn for every part of the application where we can put in a smart default choice rather than relying on the user to get involved.

API Design Trumps

There are really so many trumping situations here that it is not worth getting into. The reality is that each API is going to be drastically different, and that certain APIs are going to lend themselves to utilizing this mantra more than others. At the end of the day, though, as you’re designing your API, you need to ask yourself, how often will the user need to customize this? If its every application, then its not a candidate. If the majority of applications can use a suitable default and be fine, then there is no good reason to require the user to explicitly choose that option. The default smart choice is there to make his life easier so that he can go about getting his work done.

Conclusion

That concludes the series “Make the Smart Choice So That Your User Doesn’t Have To”. Don’t forget to read Part 1 which deals with Preferences and Part 2 that deals with User Interfaces.

Post Metadata

Date
November 21st, 2008

Author
urbansquall

Category




Comments are closed.