Services - gkresic/commons-fields GitHub Wiki

Commons-fields declares few interfaces that augment certain operations on fields-enabled objects. Providing implementations for any of these interfaces is optional.

FieldsService

Only interface that you probably will want to implement is FieldsService which will enable you to use extend using that service to incrementally extend object as more specific parts of its graph is required.

Besides usage in extend, FieldsService can be used for initial object retrieval and exposes several utility methods.

FieldsAsyncService

FieldsAsyncService is an asynchronous version of FieldsService, but with the same purpose. Use in cases where synchronous logic is not suitable (like fetching objects over the network without blocking invoking thread). For handling reponses FieldsAsyncService uses FieldsServiceHandler which should be abstract enough to serve as handler for any type of asynchronous mechanism used in concrete implementations.

Batcher

Special implementation of FieldsAsyncService is Batcher which knows how to use backing FieldsAsyncService to "batch" multiple retrievals of same entity into only one call to FieldsAsyncService.get using union of all requested attributes. This way multiple network round trips and object retrieval from backing store can be replaced with only one, saving both time, resources and network bandwidth.

One important thing to consider is when to invoke run which will actually execute all batched invocations. If client app is running in web browser (remember, commons-fields is GWT compatible as is this pattern easily portable to native JavaScript), the obvious place to schedule run is at the end of the current event loop. Consider this GWT template:

public class FooBatcher extends Batcher<String, Foo, Foo.Field> {

  public static FooBatcher get() {
    
     if (instance == null)
        instance = new FooBatcher();
    
     if (!scheduled) {
        Scheduler.get().scheduleDeferred(instance::run);
        scheduled = true;
     }

     return instance;

  }

  public FooBatcher() {
     super(FooGwtService.get()); // FooGwtService implements FieldsAsyncService<String, Foo, Foo.Field>
  }

  @Override
  public void run() {

     super.run();
    
     scheduled = false;
    
  }
 
  private static FooBatcher instance = null;

  private static boolean scheduled = false;

}

Note that Batcher is suitable for extending objects, too.

CRUDFieldsService

Opinionated (and completely optional) interface for implementing services that extend FieldsService with basic CRUD (Create, Read, Update, Delete) operations.