DataBus is a Java class library for developing highly dynamic, universal and modular applications. It allows
software modules (called components) to talk to each other, exchanging data or sending events, without knowing anything from each other.
They only thing these components needs to know is the type of data to exchange (the event type). For each event, there can be
an unlimited number of consumers and producers. Consumers can also generate new events, acting as producers (such
components are called filters).
Think of the DataBus as a number of whiteboards (one board for each type of event), where all producers can write down their data, and the
consumers can read from there (and write their responses or new data down).
- unlimited number of event types, producers and consumers
- event handling is done asynchronously (the producers do not wait for the consumers to catch up)
- each consumer has its own event handler queue, decoupling its event handling method from the bus
- recevining event order is the same for all consumers
- event receving is decoupled from the consumerss event handling
- it is possible to send events synchronously, reading a response object
- the DataBus configuration is read from a single configuration file
- each component can have a descriptor file, containing
- name of the component
- the class name of the component
- additional information
- information about the configuration of the component
Why use DataBus?
DataBus allows to build applications in a higly modular fashion. Because the individual components communicate with each other only through the
events, they are independant of each other. They can be easily exchanged, without any other component noticing. This can even
be done during runtime.
Communcation via events also requires the careful definition of the interfaces between the components. This will lead to higher code quality,
because it requires more thinking before coding. It also allows for easier testing, because the interfaces are really simple.
Using events more communication makes the components simpler - they just dont't need to know much about other components.
APD as an example
The APD program contains the following components:
These components use the following events:
- MP3 player (MADLibPlayerService or MPG123PlayerService)
- playlist handler (PlayListManager)
- LIRC remote control handler (LircControlService)
- LCDProc status consumer (LcdProcPlayStatusWriter)
- play status handler (QueueService)
The registered MP3 playing component receives Player events. The play status handler
sends a 'PLAY' command after the startup, conbtaining the first file to be played. The MP3 player then
sends regularly the curent play status, which is used by the play status handler
to determine when a song is finished. Then it sends a new 'PLAY' command, which contains the next file.
showing the curent status
The current play status send by the MP3 player is also received by the LCDProc status consumer. When
the current song changes, the new title and artist are displayed in the LCD. Additionally, each second the
time left for playing the current song is updated.
The LIRC remote control handler just takes the commands from the LIRC daemon, and sends the corresponding
Instead of using the LIRC service to control APD with a remote control, there are two additional modules:
Both modules simply send PlayerEvents. So the MP3 player just doesn't need to know about these modules, as it just cares about events.
- LCDProcControlService, which interprets keypresses from LCDProc as play command
- RemoteControlService, shich allows the control with a remote AWT client, connect via TCP