In event based systems procedures are not invoked directly, but rather a component can announce or broadcast one or more events. Other components in the system can register an interest in an event by associating a procedure with it. When the event is announced, the system itself invokes all of the procedures that have been registered for the event. Thus, an event announcement "implicitly" causes the invocation of procedures in other modules.
For example, let us consider an Integrated Development Environment for Java. Such IDE consists of tools such as editors for source code, variable monitors, a debugger, etc. Usually, such systems utilize an event based architecture. Thus, editors and variable monitors register for the debugger's breakpoint events. When a debugger stops at a breakpoint, it announces an event that allows the system to automatically invoke procedures of those registered tools. These procedures might scroll an editor to the appropriate source line or redisplay the value of monitored variables. In this scheme, the debugger simply announces an event, but does not know what other tools or actions (if any) are concerned with that event, or what they will do when the event is announced.
When an event is announced in an event based system, the system itself invokes automatically all of the procedures that have been registered for that event. That means that the system must implement a certain strategy how events are handled in the system, i.e., how events are being dispatched to registered components in the system. There exist a number of different strategies of dispatching events. Generally, we may divide these strategies into two groups:
Event based KWIC system is composed of the following components:
The existing KWIC system works as follows. The act of adding a new line to the first LineStorage causes an event to be sent to the CircularShifter module. This allows the CircularShifter module to produce all circular shifts of the line and to store them into the second line storage. This in turn causes another event to be sent to the Alphabetizer module, so that this module may sort the newly added circular shifts.
Thus, we have the following event based interactions in the system:
The current KWIC system implements Observable/Observers pattern for handling events in the system. Thus, the two LineStorage modules (the first one applied to store the original lines, and the second one applied to store the circular shifts) are implemented as Observable modules. On the other hand the CircularShifter and the Alphabetizer module are implemented as Observers. Thus, the CircularShifter is an Observer of the first LineStorage module, whereas the Alphabetizer is an Observer of the second LineStorage module.
Since the standard Java library, more specifically the standard java.util package provides the Observable class and the Observer interface, which implement the described behavior, these elements were reused to implement the Observable/Observers mechanism in the KWIC system. The following diagram shows the CircularShifter and the Alphabetizer class.
Thus, the Observer interface from the standard java.util package has only one public method: update. This method is invoked each time when an Observable object (observed by that specific Observer object) sends an event in the system. Thus, the CircularShifter and the Alphabetizer class implement this method to take their action whenever the LineStorage module that they observe sends an event. The event itself is passed as the second argument in the update method.
The second diagram shows the LineStorageWrapper class which reuses the LineStorage class from the second assignment, but extends its functionality by inheriting from the Observable class from the java.util package.
Thus, the Observable class from the standard java.util interface provides public methods that allow other objects to register themselves as Observers of objects of that class (addObserver() method). Further, the Observable class provides a method to notify Observers by sending an event in the system (notifyObservers() method). This method takes as an argument a single object of an Event class.
In the current KWIC system we apply two LineStorageWrapper objects to store the original lines and circular shifts respectively. The added functionality from the Observable class allows us to invoke notifyObservers() method whenever a new line is added, deleted or inserted in any of these two objects. This in turn causes update method in the CircularShifter or Alphabetizer to be implicitly invoked, thus allowing us to take desired actions, i.e., to produce and add circular shifts in the case of CircularShifter object or to sort circular shifts alphabetically in the case of the Alphabetizer object.
Finally, here is the diagram of the Event class from the existing KWIC system.
Note that the Event class implements a simple protocol for describing the type of an event that occurred in a LineStorageWrapper object. Thus, by setting the type of the event we may tell the Observers what happened exactly. For example, if we set type of the event to ADD, we are telling Observers that a new line has been added to a LineStorageWrapper object. On the other hand, by setting the type of the event to DELETE, we are informing Observers that a line was deleted.