Handler objects

TorgoX on 2002-03-08T05:42:10

Dear All,

There seem to be main three kinds of modern interfaces for events:

  1. You specify eventname1 => CODEREF, eventname2 => CODEREF, ... in a call to something, thereby declaring those as the handlers.
  2. You subclass the main class, and provide override methods sub eventname1 { ... } sub eventname2 { ... } ...
  3. You provide an object on which can be called $object->eventname1(...), $object->eventname2(...), ... and that object need not be a subclass of anything specific.
Now, my question is: does anything but SAX use style 3 there?


POE

Matts on 2002-03-08T07:43:36

POE's object_states are very similar to how SAX works.

I do...

pdcawley on 2002-03-08T08:38:18

Who the hell cares what your object inherits from so long as it provides an appropriate interface in whatever context. Formalizing the interface concept is nice if you're a compiler, but can be a pain in the arse if you're a programmer. And if you get the interface wrong the program will die early with a sensible error message, so everyone's happy.

Taking this approach helps a great deal if you start looking at techniques like mock objects for testing, or facade type objects that delegate everything.

Don't fret about what an object is, fret about what it does. Insisting that stuff inherits from something limits your flexibility and introduces code dependencies that don't need to be there (what if you suddenly realise that your interface base class is badly named? Have you remembered everywhere that that name is used?)

Optimize for the common case

darobin on 2002-03-08T15:07:09

SAX uses both 2 and 3. It uses 2 for drivers and filters, and 3 for simple handlers.

The reason this was so is totally deliberate: the most common case in SAX is a handler. With that approach, you only need to provide a (possibly fake) constructor and define those handlers you need. That could have been achieved using approach 2, but that might have gotten in the way of filter chains.

As for other examples of the same pattern, many GUIs and MVC approaches use it. I've seen it on many an occasion. I've even seen people use it in EcmaScript...

Java interfaces

jdavidb on 2002-03-08T18:00:17

Style 3 is Java interfaces. I loved the concept when I first heard about them, but apparently most older books don't focus on them. (Apparently Java, like Perl, has a huge backlog of obsolete information, advice, and books floating around out there.) I guess interfaces made it into SAX via Java.

Basically, an interface is like a virtual class, except there's no inheritance involved. Interfaces can be used to give you the benefits of multiple inheritance without actually allowing such. For example, to create a thread you can subclass Thread. But what if you have a Terminal object (itself subclassed from a long line of who knows what) that needs to be a thread? You can declare that Terminal implements the Runnable interface, which means for all intents and purposes that you declare Terminal implements a certain set of methods and the compiler can rely on that fact. Parameters to methods can also be identified only by interface, so Java can really do things like:

foreach my $obj ($camera, $gun, $craps) { $obj->shoot; }

but only if you declared each object as implementing a shootable interface or something like that.

I could really go for interfaces in Perl. I mean, you can program like that already, but I'd like to let the compiler know what I'm doing so it can tell me when I $cat->shoot that I messed up. (presumably)

I'm not (yet) an XML/SAX guy, so I didn't realize SAX did this. Cool. I'm also not a Java guy, so anything I said here is probably wrong. Or common knowledge. Or both. :)

Re:Java interfaces

darobin on 2002-03-09T19:12:23

Yes, that's very close to the idea. And in fact, there's a growing number of classes that implement the SAX interface while not having SAX as their central focus. They just want to be usable as SAX handlers to build their internal structure.

The way we did it is however slightly different as you are not forced to implement anything of the interface. In fact, you could provide any object as a SAX handler and it will still work, even if it implements none of the interface (quite simply, nothing will happen). This is quite useful because most of the time you don't care about the entire set of events that can occur in an XML document.