tl;dr version:  Is it better for event handlers to have one method per type of
event?  Or one method to accept all events?  Or something else?

Currently event handlers (called EventWatchers) in Test::Builder2 implement
two methods:  accept_event and accept_result.  accept_result() is a special
case to handle results (which are special events) and accept_event() takes
care of everything else.

This means you wind up writing stuff like:

my %event_dispatch = (
    "stream start"      => "accept_stream_start",
    "stream end"        => "accept_stream_end",
    "set plan"          => "accept_set_plan",
    "log"               => "accept_log",
);

sub accept_event {
    my $self  = shift;
    my($event, $ec) = @_;

    my $type = $event->event_type;
    my $method = $event_dispatch{$type};
    return unless $method;

    $self->$method($event, $ec);

    return;
}

Which isn't too bad, but it seems like make-work.

The alternative is for the event handlers to have a method for each event,
(ie. accept_stream_start, etc...) falling back to accept_event if there is no
specific handler.

    my $method = type2method($event->event_type);
    $handler->can($method) ?
        $handler->$method($event) : $handler->accept_event($method);

I chose a single method for all events for two reasons:

1) Speed.  The event coordinator doesn't have to call can() on every handler
and every event.
2) It makes it easy to write a handler that slurps up all events, like the
History object.

It turns out #1 can be made moot with some careful programming.  #2 can be
handled by falling back to a generic handler.

So now the question is one of good event handler design, which I don't have
experience with.  How does one design a good event handler?  Is the pattern
one method per type of event?  Or one method to do the dispatching?  Or
something else?


-- 
Being faith-based doesn't trump reality.
        -- Bruce Sterling

Reply via email to