Event Listener Article Index for
Event
Website Links For
Event
 

Information About

Event Listener




In Computer Programming , event listener is one of Design Pattern s that is to distribute data to objects that volunteer for it, but you
don't want to maintain a central list of where it should go, especially if it
changes over the life of a running program. You set up a registration method,
keep a list of interested objects that register themselves, and each time
something arrives, you send it to everyone who has registered.

When: Information is coming in that needs to be distributed to an unknown or
changing list of objects.

Symptoms: When information arrives, you loop through an array and call a method
in every object listed, or worse, looking through a large if/elsif chain looking
for a method or object to call. You're often adding things, which requires
changes to the array of if/elsif chain as well as creating the new object or procedure.

Also Known As: Observer .

The UML diagram below illustrates this structure:

Decide on a list of different kinds of events that are happening, and create a
channel for each of them. When something subscribes to that channel, it gets
notification of everything that comes in on it. In this case, there is one
source and potentially many recipients. If the recipients also distribute
information, there is no reason that they cannot also implement channels, though
this might require the use of threads.

package EventChannel;

sub new {
my = shift;
my = { };
bless , ;
}

sub addEventListener {
my = shift;
my = shift; ->isa('EventListener') or die;
-> = ;
return 1;
}

sub removeEventListener {
my = shift;
my = shift; ->isa('EventListener') or die;
delete ->;
return 1;
}

sub broadcastEvent {
my = shift;
my = shift;
foreach my 3 (values %) {
eval { 3->receiveEvent(); };
warn $@ if($@);
}
}

package EventListener;

sub receiveEvent {
warn "EventListener::receiveEvent not overriden to do anything useful";
}

package IOServer;
use EventChannel;

sub new {
my = shift;
my = shift;
my = {fileHandle=>};
}

sub start {
my = shift;
my = ->{'fileHandle'};
while(<>) {
->broadcastEvent();
}
}

# WonderWedge

package WonderWedge;
use EventListener;
@ISA = ('EventListener');

sub new {
my = shift;
my = { };
bless , ;
}

sub receiveEvent {
my = shift;
print @_;
}

# main

package main;
use WonderWedge;
use IOServer;

  • STDIN;

  • ->addEventListener(new WonderWedge);

->start();

An event itself could, and often should, be represented as an object, too. In this example, we'll leave it as a scalar.

I have a Gnutella servent that allows user defined code to attach to it as daemons, in addition to a few built in ones. If I broadcast every message to every daemon object, I would be spending more time delivering messages than processing them, since most daemons aren't interested in most messages. Instead, interested daemons can register interest in connection notices, pong packs, search requests, and many other things that come in over the network. In fact, connections are presented as daemons themselves, and they listen for requests to relay or broadcast information from other daemons in the system. Since connections appear and vanish all of the time, it would be impossible to know in advance where to send packets. The solution is to have interested parties request them.

An advanced version of this is a ConstraintSystem.


EXTERNAL LINKS

  • http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/131499 - in Python

  • http://www.newsisfree.com/click/-4,16938591,2532,15945,mail/ - in Java (not working anymore)

  • http://www.onjava.com/pub/a/onjava/2005/03/23/executors.html - Java 1.5 Flexible Event Delivery with Executors


''The article is originally from the Perl Design Patterns Book ''