Michael Higgins ([info]sui66iy) wrote,
@ 2008-07-14 21:52:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Abstraction and the left hand that doesn't know what the right hand is doing
A bug popped up the other day that is an example of a frustrating class of computer problem. Here's how it happened:

I have some code that presents a nice UI for managing a certain kind of data. Originally, it was designed to handle data from a particular source. Later on, another source for the "same" kind of data was added to the program. Fortunately, my code is "properly" abstracted, so the UI doesn't care where the data comes from, and I can use it either way.

Unfortunately, and herein lies the problem, a requirement arose later that if the data comes from source A, the UI should behave very slightly differently than it should if it comes from source B. Unfortunately, my UI can't tell the difference between data that comes from one source or another. In essence, the program has forgotten something that it needs to know.

There are several solutions to this particular instance of the problem. One obvious one is to change the API to the UI, to add a little parameter that controls activating the different presentation. Another (not so good) solution would be to try to add intelligence to the UI piece that analyzed the data and looked for some hint that it should display it using method A or method B. (Sometimes you have to do the latter when the API is not under your control.)

The frustrating part of this situation is that I think it's inevitable. To make computer systems tractable, you have to use abstraction. Abstraction, to me, means to remove inessential details leaving behind the essence. The problem is that it can be awfully difficult to figure out what the essential details are and what is noise. If you leave too much out, you have this forgetfulness problem where information is lost as it goes through the system. If you put too much in, though, your abstraction is not abstract, and it becomes hard to use in more than one context.

To some extent good design work can mitigate this problem. It does help to think things through up front, and talk them over with others. But it can't solve it completely. We are not terribly good prognosticators, and requirements change over time. If you control all the relevant code, re-factor aggressively. That will beat the code into a useful shape fairly rapidly. If you don't control the code, be prepared for ugliness.


(Post a new comment)


[info]cellio
2008-07-15 02:34 am UTC (link)
Instead of changing the API to pass a new parameter or writing code that guesses, can you change the API of the data source to support a "who am I?" method? It sounds like you're looking for the equivalent of instanceof...

(Reply to this) (Thread)


[info]sui66iy
2008-07-15 12:46 pm UTC (link)
Potentially. This data goes across a wire, so it gets serialized between origination and the UI, which are in different implementation domains, but yeah, you could enrich the data representation with something like that. So that's at least a third option. I think it has similar trade-offs: if anyone else is consuming that data stream, we must make sure they are prepared to deal with little bits of extensibility like that (but that's sometimes easier than changing an API).

(Reply to this) (Parent)(Thread)


[info]cellio
2008-07-16 01:54 am UTC (link)
I think identifying the source (and type) of data in a data feed is probably more common than passing that information as a parameter, so that might be an argument in favor, assuming you can handle the format change for other recipients of the data feed. I mean, I don't know your specific situation here, but are you sure that this API is the only place where you would need that info? If you're likely to need it elsewhere, putting it in the feed once seems more extensible than modifying each interface where it matters.

(Reply to this) (Parent)(Thread)


[info]sui66iy
2008-07-16 03:07 am UTC (link)
This actual instance of the problem is so minor that any of the fixes would be okay (well, maybe not the guessing one. It's just so ugly!). I think the interesting question is what patterns help in general? I happen to like extensible data formats, but there are similar complexity complaints. If lots of different parts of a system are adding little bits and pieces of extended data that is required to make other parts of the system behave correctly, you can get bloat (both in the data itself and in the code that needs to check for the extensions and validate them and react correctly if the needed extension isn't present). In a simple system where producers and consumers of data are fairly segregated, it's probably pretty easy. But if the data moves along a complex chain and gets modified at each step, and their are internal dependencies in the data, you've got to be careful that you don't step on anyone's important little piece of the data as you go. And so this is why people layer more complex mechanisms into their formats, like roles or schemas, so that you can split a format into semantically independent and semantically related pieces in a machine-checkable way...

(Reply to this) (Parent)


Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…