Shortly after adopting the Model-View-Presenter pattern, I found myself copying the same service call into multiple presenters, as both a navigation panel and a main content area can sometimes display the same information. I decided to factor out the repeated service calls into a Service Facade (for lack of a better name) and inject the facade into each presenter that’s needed.
@Inject public AddPrayerListPresenter(Display display, EventBus eventBus, PrayerListServiceFacade prayerListServiceFacade) { super(display, eventBus); this.prayerListServiceFacade = prayerListServiceFacade; bind(); }
Inside the service facade, I use constructor injection to get the event bus and dispatcher the same as in a presenter.
@Inject public PrayerListServiceFacade(final EventBus eventBus, final DispatchAsync dispatch, RoaModel roaModel) { this.dispatch = dispatch; this.eventBus = eventBus; this.model = roaModel; } public void refreshPrayerLists() { GWT.log("Calling actionFindLists", null); // Fire event that marks start of the service call so listeners // can show the AJAX wait thingy if desired eventBus.fireEvent(new RefreshingPrayerListsEvent()); dispatch.execute(new FindPrayerListsAction(), new AsyncCallback<FindPrayerListsResult>() { @Override public void onFailure(Throwable e) { GWT.log(e.getMessage(), e); Window.alert(e.getLocalizedMessage()); } @Override public void onSuccess(FindPrayerListsResult result) { eventBus.fireEvent(new PrayerListsModifiedEvent(result.getPrayerLists())); } }); }
The refreshPrayerLists() method contains the code that had been common to multiple presenters. There is one difference, however. When a presenter calls a service, it typically passes a DisplayCallback object, which gwt-presenter uses to call the view’s startProcessing() and stopProcessing() methods so you can show an Ajax wait thingy (er, progress indicator?) I could add a Display argument to the service method and create a DisplayCallback as usual; however, in this case, I want the refresh method to be called only once in conjunction with the event that necessitates a refresh (say, a new prayer list is added). And I want multiple widgets to be notified when the service call begins, and when it finishes. To accomplish this, I pass only a regular AsyncCallback object and fire an event both before and after the service call, to which any interested widget can listen.
In summary, the service facade provides a way to group all related service calls in one place and to factor out common calls from multiple presenters. Now all I need is a better name for it, as it sounds a little scary for my taste…