The Correspondence Community

Correspondence is about agreement. Every person, every application, every machine involved in the correspondence network comes to agree upon the history of the objects that they share. This set of people, applications, and machines is collectively known as the Community.

The Community object
In code, the Community is represented by a Community proxy object. This proxy is the center of all Correspondence operations. We've already seen the addObject method, which puts a Correspondence object into the system. Here's a complete list of methods:

  • addObject(T prototype) : T {where T extends CorrespondenceObject}
  • getObject(T prototype) : T {where T extends CorrespondenceObject}
  • setModules(List<Module> modules)
  • addType(Class correspondenceObjectClass) : Community
  • addFieldSerializer(Class fieldType, FieldSerializer fieldSerializer) : Community

The addObject method is by far the most used. It shares an object with the rest of the community. It places it in the database, attaches it to related objects (via queries), and sends it out over the network.

The addObject method takes a prototype. An object's predecessors and fields define its identity. So if an object matching the prototype is already in the Community, that existing object is returned. If no matching object is in the Community, the new object is added and returned.

The getObject method also takes a prototype and returns an object. The difference is that getObject will return null if the object is not currently in the Community. AddObject is used to express intent, whereas getObject is used just to look something up.

Initializing the Community
The other three fields are used to initialize the Community. SetModules assigns a list of Module objects. A Module is an interface with only one method: registerTypes. RegisterTypes takes the Community object and calls the other two methods: addType and addFieldSerializer. This pattern allows collections of Correspondence object types to be grouped together as reusable components.

The addType method registers a Correspondence object type with the Community. In order for addObject, getObject, and Query to work properly, a type must be registered with the Community. AddType is typically called from within a Module. This method returns the Community itself, so that it can be chained with other calls to addType.

The addFieldSerializer method is used less often. It registers a strategy object that reads and writes fields to binary streams. The common data types (int, float, string, date, UUID, etc.) are registered by default. You can define a custom data type, implement the FieldSerializer interface, and register it within a Module. Most of the time, however, the predefined field types are sufficient.

The getCommunity method
Every Correspondence object has direct access to its Community. Call the getCommunity method within a Correspondence object any time you want to perform an action. The typical pattern (as we've seen with mutable properties) is to call getCommunity().addObject( new ChildObject(this, more parameters)).

Adding an object to the Community causes it to be returned from relevant Queries. If that Query is used to get a list of children, then the object appears in that collection. If it is used to get the value of a mutable property, that new value appears. If it is used to cause the exists method to return false, the appropriate object is deleted. All of these changes take place automatically. Queries are dependent behavior; adding an object to the Community is independent behavior.

Coming soon
I realize that this is a lot of talk about code without being able to compile any of it. I'm getting the Java version of Correspondence ready to share with you. Within a week or two, you will be able to download a JAR file and sample code. The C# version is about a month behind. In the mean time, there is one last concept I'd like to present, so the next post will talk about the StorageStrategy interface.

Leave a Reply

You must be logged in to post a comment.