CroftSoft / Library / Tutorials

Interface Slot

David Wallace Croft

2007 Jan 28 Sun


In my Java programming, I use queues everywhere these days. It used to be I would just use them for network messaging. Then I also started using them for passing messages between threads or ensuring that all requests were served within the same phase of a loop. Now I also use them to promote loose coupling between objects, especially the model, view, and controller (MVC). Instead of a direct method call from one object to another, I have the calling object append a message to a queue for later processing by the receiver.

This means that I no longer share object references between the MVC classes. Instead I now provide queue references. For example, a controller object will append requests to modify model state on the model request queue instead of calling model mutator methods directly. Likewise, a model object will post state update events to a view queue instead of calling a listener method on the view object directly.

I was passing queue references to the constructor methods of these objects so that they could communicate with each other. It occurred to me that I was providing too much access to the objects that needed a queue reference simply to send messages, not to receive them. For the same reason that I created the read-only accessor interface, I wanted to create a write-only message sending interface.

I decided to call it Slot after a mail slot that you might see embedded in the wall of a post office. With a mail slot, you can only insert messages; you cannot look to see what else has been inserted or withdraw messages. There is really just one type of interaction that you can have with a mail slot.

Another feature of a mail slot is that you generally have no idea how your message will be processed on the other side. It could be received by the intended recipient immediately; it could be stored for later reading; it could be relayed; it could be copied and broadcast to multiple recipients; it could be discarded unread. Assuming you believe in the benefits of abstraction, you simply trust that the right sort of thing will happen once you let go of your message and let it slip into the system.

The following is what this simple interface looks like. You can see that I am only exposing the offer() method from interface java.util.Queue.
    package com.croftsoft.core.role;

    /***********************************************************************
    * Mail slot for receiving messages to be processed, stored, or relayed.
    *
    * @since
    *   2007-01-28
    * @author
    *   <a href="https://www.croftsoft.com/">David Wallace Croft</a>
    ***********************************************************************/

    public interface  Slot<E>
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    {

    public boolean  offer ( E  e );

    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    }

Here is how you might create an instance of Slot using an anonymous inner class as an adapter:

    final Queue<Request>  requestQueue = new LinkedList<Request> ( );

    final Slot<Request>  requestSlot = new Slot<Request> ( )
      {
        public boolean  offer ( final Request  request )
        {
          return requestQueue.offer ( request );
        }
      };

    final Requester  requester = new Requester ( requestSlot );

    final Server  server = Server ( requestQueue );

The interface Slot reference is passed as a constructor method argument to the Requester and will probably be stored as a final instance variable. Using this layer of indirection obviates the chicken-and-egg problem of passing references as constructor arguments when each object needs a reference to the other but one must be instantiated first.

If you see a constructor argument that accepts a Queue as an argument, you might have to read further to see how it is used, whether for sending, receiving, or both sending and receiving messages. This is not so with an argument of type Slot. Note that class Server receives a direct reference to an instance of interface Queue via its constructor method since it must be able to call the poll() method in order to process the requests. Perhaps a simpler interface with just that method is all it needs. If so, the interface might be called Pollable or something a bit shorter.

 
 
 
CroftSoft
 
 
About
Library
-Books
-Code
-Courses
-Links
-Media
-Software
-Tutorials
People
Portfolio
Update
 
 
Google
CroftSoft Web

 

Creative Commons License
© 2007 CroftSoft Inc.
You may copy this webpage under the terms of the
Creative Commons Attribution License.