July 25th, 2007

headwall, frustration

How Not to Design an API

Sorry I've been out of contact lately! With Rakeela and I sharing one computer, I haven't had the chance to post much. I've been quite busy, but we've been doing well. I'd probably still be at work, except there was a power outage in my building; Microsoft basically shuts down when there's no power, as everything is done on computers. I walked past a main computer lab on the way out; the standard flourescent lights were strobing (not flickering, but strobing disturbingly regularly at a high rate; that's not supposed to happen), and four people were at the circuit breaker panel, flipping switches and cursing, while the distinct scent of burning computer parts hung in the air.

But I was ready to go home; I'd accumulated something of a headache. I can't get into details, but: the names of products have been changed to protect the totally fucking guilty.

Consider an interface to a tool to track information about software. We'll call it "Program Something". The designers of Program Something created an API for other software to be written to manipulate the database and access all the same data that can be reached through the UI; this was originally the Program Something API, then the Program Something Object Model, and now it's the Program Something Software Development Kit, resulting in the acronym of PSSDK, which is, for some reason, rarely pronounced. (This is the actual acronym.)

Let's say the unwitting new SDET has been assigned to use the PSSDK to write a program to identify and migrate data on one particular program from one Program Something datastore to another. And the data templates have all changed, as does the formatting of equivalent fields, but the source fields were never consistent in the first place; it's a monster of sequential regular expressions now. And the original spec was for disposable code, but I never write anything to be unmaintainable; it turns out to be a good thing, as I have since heard that other teams want to use the tool once I finish it.

The data elements can be stored in a special tree structure: to show dependencies between them, each DatastoreItem is aware of its dependency list and which DatastoreItem- if any- is its parent. The API for retrieving that last part is a little... interesting.

There's a data type just to represent dependency relationships. We'll call it a DependencyLink. There's a function to get the upwards DependencyLink for any particular node; we'll call it UpDependency. The return type of UpDependency is a handle (this is C#) to a DependencyLink.

Let's consider a DatastoreItem called foo. Let's say foo depends on bar. So foo.UpDepenency() gives a Dependency Link from Bar to Foo.

Now let's say foo depends on nothing. Now what would you get if you called foo.UpDependency()? Maybe a special DependencyLink that represents "no link", maybe a null reference. Either of these would be reasonable.

DependencyLinks is a collection of DependencyLink objects. It's used if you call DownDependencies(); it returns all the downward dependency links in a DependencyLinks object. The only relation between DependencyLink and DependencyLinks is that the latter is a collection of the former; neither inherits from the other along the class hierarchy.

If you call foo.UpDependency() when foo does not depend on anything, the return is a DependencyLinks with no DependencyLink objects associated- an empty collection.

...from a functiopn with return type DependencyLink. Through a handle of type DependencyLink.

Any more questions about my headache?
  • Current Music
    Rakeela playing Super Smash Bros. in the background