Designfrage: Wie nutzt man GWT-RPC-Aufrufe lokal etwa bei Offline-Anwendungen?

Standardmäßig sieht es ja im “normalen” entfernen RPC-Aufruf so aus: Als erstes die Schnittstelle:

public interface ContactRpcService extends RemoteService {

  Contact getContactById( long id );

}

Dann die zugehörige Async-Schnittstelle:

public interface ContactRpcServiceAsync {

  void getContactById( long id, AsyncCallback<Contact> callback );

}

Der Client hat nun so was wie

ContactRpcServiceAsync contactService = GWT.create( ContactRpcService.class );

contactService.getContactById( contactId, new DefaultCallback<Contact>() {

  @Override protected void handleResponse( Contact response ) {

    ….

  }

} );

DefaultCallback ist eine meine abstrakte Klasse, die AsyncCallback implementiert, aber das ist jetzt nicht so wichtig.

Auch etwa anders mache ich noch, damit ich weniger schreiben muss; ich habe mir eine Klasse Rpc deklariert, mit Konstanten für alle GWT-creates():

public class Rpc {

  private Rpc() {}

  public final static ContactRpcServiceAsync  contactService = GWT.create( ContactRpcService.class );

  // … un ddie Anderen

}

Normalerweise sieht es also bei mir so aus:

Rpc.contactService.getContactById( contactId, new DefaultCallback<Contact>() {

  @Override protected void handleResponse( Contact response ) {

    …

  }

} );

Damit nun Rpc.contactService.getContactById() im Offline-Modus etwas anderes macht, kann man zum Beispiel folgendes tun: Rpc.contactService stammt nicht von GWT.create(), sondern ist ein Proxy. Falls nun der Remote-Fall gewünscht ist, delegiert man an an die echte Rpc-Implementierung, andernfalls an eine lokale Variante.

public class Rpc {

  private Rpc() {}

  public final static ContactRpcServiceAsync  contactService = new ContactRpcServiceAsync() {

    private final ContactRpcServiceAsync delegate = GWT.create( ContactRpcService.class );

    private final ContactRpcServiceAsync local = new ContactRpcServiceAsync() {
      @Override public void getContactById( long id, AsyncCallback<Contact> callback ) {

        // hier alles lokale machen, also etwas aus dem Cache holen. Wenn alles gut geht, und die Daten vorhanden sind, dann aufrufen
        callback.onSuccess( result );
      }

    };

    @Override public void getContactById( long id, AsyncCallback<Contact> callback ) {

      wenn der remote Fall

        delegate.getContactById( id, callback );

      andernfalls

        local.getContactById( id, callback );

    }

  };

}

Über Christian Ullenboom

Ich bin Christian Ullenboom und Autor der Bücher ›Java ist auch eine Insel. Einführung, Ausbildung, Praxis‹ und ›Java SE 8 Standard-Bibliothek. Das Handbuch für Java-Entwickler‹. Seit 1997 berate ich Unternehmen im Einsatz von Java. Sun ernannte mich 2005 zum ›Java-Champion‹.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.