/ Papers / The Messaging System in RCOS.java

RCOS.java Home PageAn Animated, Simulated Operating System in Java

The Revised Messaging System in RCOS.java

Andrew Newman

Passive Notification

COAD p224

Java 1.02 AWT Event Model

Much like the original RCOS.java messaging system.

Java 1.1 AWT Event Model

Describe the different classes and interfaces.
p509 Thinking in Java

Observable

Java.util.Observable
p193 Hacking Java

Java Beans Notification

p99-107 Special Edition Use Java Beans
p271 Coad differences.

Infobus Notification

p275 Coad

The Original Messaging System

Outline original C++ version and its conversion to Java.

Outline of C++ system.

The conversion to Java lead to a very procedural based solution.  This was due to it being derived from the C++ system and the lack of knowledge in how to produce object orientated based system.

Initially any object that implemented "SimpleMessageHandler" would register to a given post office.  The job of the post office was to record the registered objects and send the messages to the registered objects.

The system relied upon the base object type "Message".  This object contained a Source, Destination, Type and Body.  The first three were strings and the body an Object.  The post office object would use the destination to parse the send object to the appropriate registered object.  The type attributed would be used by the receiving object to determine whether it handled it or not.  The body was used to store any primitive (in their object form) or complex data types.

The system relied upon the following common methods:
SendMessage(Message) - The message is sent to the Post Office.
ReceiveMessage(Message) - Checks to determine whether the object is valid and passes it (if okay) to ProcessMessage.
ProcessMessage(Message) - In a series of if-then-else statements it checks to see what type the message and proceeds to do some action if it matches.

Improving the Messaging System

A new system was considered in order to provide a more object orientated approach to achieve messaging.  The criteria of the messaging system was that it must increase the readability and maintability of the system while encouraging code reuse.  In this was it was decided that a distinction between messages being sent be enhanced.  Two distinct post offices were created for the Operating System and for the Animator Office.  The mimiced the destinction made already within the system.  For simplicity the operating system and animator components know only of their post office and the components connected to them.
 

MessageSystem

The messaging system divided all messages into three categories:

Visitor Pattern

One of the important effects of the Visitor pattern used in RCOS.java is the ability to arbitrarily add functionality to object without modification of them.  This simplifies the introduction of extending RCOS.java functionality.  This technique is known as “double dispatch”.  However, Java is a “single dispatch language” in that the method executed is based on the type of the received object.

The benefits of this pattern are:
1/ Reduction in the amount of code by removing many long and complicated if-then-else statements.  The determining factor of whether an object processes a message is not based on arbitrary conditions.
2/ Coherence within a particular message object.  The code for each message is contained inside the appropriate message.
3/ Complicated objects or primitive data types can be used inside the object without casting or creating ad hoc external objects.
4/ New messages do not require new code to be added to handle the message; rather the message is modified instead.
5/ The determining factor of whether a message was handled was based on arbitrary conditions.
6/ Increased encapsulation of data and implementation hiding.

When the visitor pattern was implemented a simplified the process message to a few lines of code for each receiver.  The message object interface to outside code became well defined, attributes were kept encapsulated and access was allowed via methods.

Related to the MVC Pattern is double dispatch.

Adapter Pattern

The messages are broken up into three destination categories:


Now there are adapters of the abstract classes.  Each abstract class contains a “doMessage” for each possible receiving class.  The adapter class implements the respective abstract class with empty methods.  Each message then extends the adapter class and overrides only the necessary methods.

Command Pattern

A useful pattern to overcome the problem of invoking arbitrary methods in an object is the Command pattern.  This is essential in allowing the interface to allow undoable operations.  This is an important principle of user interface design especially in an educational environment [impressive link here].

Each command in the RCOS.java system is decoupled i.e. the button pressed invokes a messaging object that performs the task rather than performing the task directly.  This enables object performing the task to save any relevant information before executing so that it may be undone at any time.  Meanwhile a listener object records all of the operations that have occurred.

In RCOS you have a Message Object:
doMessage(receiver type) – stores state and carries out some operation based on receiver type.
undoMessage(receiver type) – undoes operation based on receiver type.
boolean undoableMessage(receiver type) – returns true of false if message can or can't be undone.

Post Office Object:
Vector vMessages – Vector of messages which can be undone.
sendMessage() – sends message to all Post Offices.
localSendMessage() – sends message to local objects listening.
undoMessage() – sends an undo message to all listeners.

Model-View-Controller Pattern

The Model-View-Controller design pattern originated in Smalltalk and specifically use in user interface design [Gamma et al 1995].  It's probably most used in Java in creating user interfaces, too.  The purpose of the MVC architecture is to separate the user interface from the underlying application (model).  The user interface is split up into the view (output) and the control (user input).  The model should be self-contained and free of external requirements of the user interface.

This is implemented to ensure that:

The initial development of RCOS.java consisted of one programmer working on the user interface while the others worked on components of the operation system (message passing, file system, CPU, etc.).  This ensured that the animation was dependant only on predefined messages it would receive from the operating system.

By design RCOS.java has a large hierarchy of class files.  The Animator package is split by operating system components i.e. Animator.CPU, Animator.Disk, etc.

Operating system, animators and universal sections divide the messaging system.  The operating system and animation sub-systems have their own post office designed to send message to each other and to registered components within the designated area.
 

Advantages over old messaging system

Allows multiple complex data objects to be combined for message transport.  Instead of creating external objects for specific messages or sending multiple messages with different names (like UpdateFileList and UpdateDirectoryList).

Reduction in and elimination of overlapping the usage of the messages.  By clearly defining who receives the message and what it contains the removal of several unneeded messages (due to overlapping with other messages) could occur.  There was also the case where objects (especially animators) would determine which object was sending the message to determine whether they should process the message or not.  This indicated that there were messages that were being used for two or more purposes.  These were also eliminated.

Ownership of messages is easier for two reasons:

This contrasts with the old system where messages could create new ones in an ad hoc manner and their was no real way in the source code to determine which message would be sending which objects without looking through the entire source.

Objects are not cast when received.  The default messaging object had only one message contents object (Object) that was then cast to the required type e.g. Integer, RCOS defined object like RCOSProcess, etc.  Instead each object contains the required content type.  No casting is needed.

The removal of the code blocks within the series of if-then-else and moving them to separate methods led to a greater formalisation of what each object within the system was to perform.  Also, the appearance of common methods and data structures lead to the improvement of code reuse.  Similar sections of code that were used to process two or three messages were converted into methods for reuse.  Where appropriate these were made publicly or privately accessible.
 

Improvements

The use of inheritance or composition rather than a flat message objects.  Currently, the system has separate messages for each task, whether or not their are similar messages with similar tasks.  Messages that use system objects (like RCOSProcess) use composition to achieve similar tasks within different messages.  Further aggregation of common objects passed inside messages and further sorting of messages into packages based on sender or sendee would increase reusability.

Implementing of the Visitor pattern to other areas of RCOS.java.  Such as the CPU and Kernel.