Monday, 23 April 2012

Java Interfaces in Google Protobuf

Google Protobuf: Excellent idea, well executed but only if.....

[I have put this project on hold as I'm occupied with something else. I was concerned with enums in messages and composition of messages. I also came across Protostuff which has its own .proto interpreter and uses reflection to inject messages in to POJOs. You can also use Annotations to define the .proto message spec. TJ]


A proposal to add interface decoration to Protobuf generated messages.

Background

Google Protobuf is a language that defines how one encodes messages on a transport.

Like everything Google - it is well thought out, not over designed and intelligently implemented. It is target language agnostic, efficient and allows for managed upgradeability.


Except: 
The .proto message compiler (protoc) only creates rich (final) Message classes. These contain the immutable messages and access to builders for creating new messages.


Java Interfaces

Perhaps the best language feature of Java (there are many more...) is the Interface. It is a traditional implementation-free definition of the contract that an implementing object must provide.


It has a number of advantages including:

  • Using an interface means that you can change the implementation but maintain the contracted functionality;
  • You can write collaborators that work on objects that implement the interface without any other knowledge or dependencies on the implementation;
  • When testing classes that use the interface you can stub easily stub or mock out the interfaced object;
  • And many more.

Using protobuf generated message classes in the real world

The only problem is that a protobuf Message does not implement a simple interface - typically when you are receiving messages over a transport - you want to pass the messages on to handlers that know nothing about how they were encoded over the transport - indeed you might be handling the same message from different sources. OO would suggest that you're handlers would only require objects that allow access to he properties that they require to do their work. As the Protobuf Generated Message class has no means of attaching an interface one has to take one of two routes:

  1. Create a new Object from the Message (probably using a factory) that implements your interface; or
  2. Create a delegate that when you give it an object it extracts the relevant part.
The first doubles your number of objects created (one for the message and one for interface implementation. The second requires that extra complexity on the delegate and an extra call per property retrieved.


Proposal - decorating Generated Messages with Interfaces

My suggestion is to allow one to write an interface to encapsulate the properties you require from any message you will be processing and then decorate the Generated Message with that interface.


For instance, if we have a message in spotrate.proto:
message SpotRate {
 required uint64 timestamp = 1;
 required string currencyPair = 2;
 required double rate = 3;
 required string trader = 4;
 // ... and so on
}
Then if our message consumer was only interested in the currency pair andrate we would create an interface in ISpotRate.java:
public interface ISpotRate {
 String getCurrencyPair();
 double getRate();
}


[HERE - show example new syntax and usage]

No comments:

Post a comment