Service Domain Model

This is the sixth in the sequence of blog posts regarding some of experiences in creating Trading and eCommerce platforms at Adaptive. The previous post can be found here.

In this post, we look at how the Parse Tree generated from our Service Definition DSL can be transformed into a Domain Model that can be reasoned about and further transformed into useful artefacts.

Transformation

The process of transforming a Parse Tree into a Domain Model can be achieved using the Visitor Pattern. Using this technique you recursively walk down the Parse Tree building up the Domain Model in parallel as you descend.

Model

Here we set out the Domain Model that is generated. We have presented this as a set of pseudocode interfaces. For each interface, there is a summary and a description of the various properties.

The Model interface encapsulates the whole Domain Model. It consists of a Namespaces property, a collection of Messages and a collection of Services.


    interface Model {
        Namespaces namespace();
        Iterable messages();
        Iterable services();
    }

Namespaces

The Namespaces interface defines the various namespace strings to be used for each platform when it comes to generating code.


    interface Namespaces {
        String javaNamespace();
        String dotnetNamespace();
        String cppNamespace();
        String htmlNamespace();
    }

Message

The Message interface is an abstract representation of a Message. Each message has a unique name and a MessageType.


    interface Message {
        String name();
        MessageType type();
    }

The MessageType enumeration defines whether a concrete message is COMPLEX, i.e. made up of a number of fields or and ENUMERATION.

   
    enum MessageType {
        COMPLEX,
        ENUMERATION
    }

The ComplexMessage concrete interface extends the abstract Message and introduces a collection of Fields.

   
    interface ComplexMessage extends Message {
        Iterable fields();
    }

The EnumerationMessage concrete interface extends the abstraction Message and introduces a collection of enumeration values.

   
    interface EnumerationMessage extends Message {
        Iterable values();
    }

The Field interface is an abstract representation of a Field. Each field has a unique name a type and flags to specify whether it's optional, required or repeated.

   
    interface Field {
        String name();
        FieldType type();
        boolean required();
        boolean repeated();
    }

The FieldType enumeration defines whether a concrete field is PRIMITIVE, i.e. a boolean, string, double etc. of a nested Message.

   
    enum FieldType {
        PRIMITIVE,
        MESSAGE
    }

The MessageField concrete interface extends the abstract Field and introduces a nested Message.

   
    interface MessageField extends Field {
        Message message();
    }

The PrimitiveField concrete interface extends the abstract Field and introduces a PrimitiveType.

   
    interface PrimitiveField extends Field {
        PrimitiveType type();
    }

The PrimitiveType enumeration defines a set of primitive types that are then mapped to concrete types that are idiomatic to each platform.


    enum PrimitiveType {
        STRING,
        BOOL,
        INT,
        LONG,
        DOUBLE
    }

Service

The Service interface defines a service in terms of a unique name and a collection of Operations.


    interface Service {
        String name();
        Iterable operations();
    }

Operation

The Operation abstract interface represents an operation with a name that is unique for the parent Service and an OperationType.

   
    interface Operation {
        String name();
        OperationType type();
    }

The OperationType enumeration defines a set of operation types that conform to the various messaging protocols.

   
    enum OperationType {
        REQUEST_RESPONSE,
        REQUEST_ONLY,
        STREAM,
        REQUEST_STREAM,
        PUBLISH_SUBSCRIBE
    }
Request-Response Operation

The RequestResponseOperation concrete interface extends the abstract Operation and references the request and response Messages.

   
    interface RequestResponseOperation extends Operation {
        Message requestMessage();
        Message responseMessage();
    }

Request Only Operation

The RequestOnlyOperation concrete interface extends the abstract Operation and references the request Message.

   
    interface RequestOnlyOperation extends Operation {
        Message requestMessage();
    }

Stream Operation

The StreamOperation concrete interface extends the abstract Operation and references the update Message.

   
    interface StreamOperation extends Operation {
        Message updateMessage();
    }

Request Stream Operation

The RequestStreamOperation concrete interface extends the abstract Operation and references the request and update Messages.

   
    interface RequestStreamOperation extends Operation {
        Message requestMessage();
        Message updateMessage();
    }

Publish-Subscribe Operation

The PublishSubscribeOperation concrete interface extends the abstract Operation and references the request and update Messages.


    interface PublishSubscribeOperation extends Operation {
        Message requestMessage();
        Message updateMessage();
    }

Summary

In summary, we have described how a Parse Tree can be transformed into a Domain Model by recursively walking the tree using the Visitor design pattern and generating Model objects in the process. We have also defined a set of interfaces that can be used to model such a domain.

The next post can be found here.

 

John Marks

CCO and co-founder,
Adaptive Financial Consulting



×

Contact us

    By pressing "Send" I agree that I am happy to be contacted by Adaptive Financial Consulting. I can unsubscribe at any time. You can read more about our privacy policy here.