devork

E pur si muove

Registering callbacks: to quack like a duck or tell which bit will quack the duck way?

Friday, February 05, 2010

When you have someplace where you register a set of callbacks you have a few options:

  1. Use an interface-style API. I.e. you have a Mixin style class defining the methods expected to be present, probably just raising NotImplementedError. You then just pass in the entire object to the .register() function.
  2. Just try if it quacks like a duck. IMHO this is just the pythonic equivalent of the above, simply without the explicit mixin class.
  3. Explicitly pass in the callback functions. This would be something like: .register(func1, ...). Secret benefit here is using the result of functools.partial() and things like it.

What I don't like about the first two options is that you force the method name of the callback onto the user. The third option allows you to achieve the same but at the cost of a more complicated register function. But I tend to prefer it because it's more explicit and it avoids "hiding" things in the object (via the mixin) thus keeping the interfacace between caller and callee cleaner.

Are there other design considerations when making this choice? Maybe there's already an essay somewhere exploring these ideas in more detail then I'm doing here?

Friday, February 05, 2010 | Labels: |

1 comments:

Marius Gedminas said...

What's the difference between option (1) and option (2)? Surely you're not suggesting an explicit isinstance check on the argument passed to register? Other than that, having a base class you can (optionally) use is nice, at least for documentation purposes (one example is worth a thousand words of description).

Regarding single object with multiple attributes versus multiple plain callables, I guess both are valid choices and it depends on the actual situation which one is to be preferred. If the callbacks are independent, I'd go with multiple callables. If they're tightly related, I'd go with a single object.

New comments are not allowed.

Subscribe to: Post Comments (Atom)