Continuing the topic Advises for beginners I am going to talk about the most comfortable way to incapsulate server’s methods calls. Let’s call it ServiceBase pattern. It is a base class for all your possible services (bunch of methods which correspond to the server ones):
class ServiceBase
{
public function ServiceBase(destination : String,
resultHandler : Function = null, faultHandler : Function = null)
{
_resultHandler = resultHandler;
_faultHandler = faultHandler;
_remoteObject = new RemoteObject(destination);
}
protected function call(name : String, args : Array) : void
{
CursorManager.setBusyCursor();
var operation : AbstractOperation = _remoteObject.getOperation(name);
operation.addEventListener(ResultEvent.RESULT, onResult);
operation.addEventListener(FaultEvent.FAULT, onFault);
operation.send.apply(operation, args);
}
protected function onResult(event : ResultEvent) : void
{
CursorManager.removeBusyCursor();
if (_resultHandler != null)
{
_resultHandler(event.result);
}
}
protected function onFault(event : FaultEvent) : void
{
CursorManager.removeBusyCursor();
if (_faultHandler != null)
{
_faultHandler(event.fault);
}
}
private var _resultHandler : Function;
private var _faultHandler : Function;
private var _remoteObject : RemoteObject;
}
I have seen similar solutions in different projects but they were not that useful. The class is not very clear for understanding itself but with the second one it will be easier to get the idea:
class GuestbookService extends ServiceBase
{
public function GuestbookService(resultHandler : Function = null,
faultHandler : Function = null)
{
super("GuestbookAction", resultHandler, faultHandler);
}
public function getGuestbookEntries() : void
{
call("getGuestbookEntries", arguments);
}
public function getEntryById(id : Number) : void
{
call("getEntryById", arguments);
}
public function updateEntry(id : Number, text : String) : void
{
call("updateEntry", arguments);
}
}
That class is a service for working with a guestbook. It has all the methods which server class GuestbookAction (Servlet, Facade depends of platform) do. The constructor has non-required arguments resultHandler and faultHandler, these functions are invoked with the result of a server callback or error information. Usage example:
new GuestbookService().updateEntry(5, "Nice solution!");
or
new GuestbookService(onGetEntryById).getEntryById(6);
function onGetEntryById(result : GuestbookEntry) : void
{
_list.addItem(result);
}
The main feature is that we do not save the reference to GuestbookService instance, it is unnecessary after the call is completed. That issue may be useful if we are going to make multiple server calls. In that case we could create a service instance for each call.
I like this approach much more then low level syntax based on RemoteObject instance because it is simple and clear. That kind of inheritors could be also generated automatically on the base of structure of server classes. In that case you get a total control over server and client methods accordance. If there are some mismatches the compiler will not be able to build your project.
That kind of solution may also help you with unit-testing. You can replace the base class of your service with something like MockServiceBase.