MVCS: Services in Robotlegs

Nach der Einführung in das Robotlegs ActionScript-Framework gibt es nun ein weiteres Robotlegs-Beispiel. Schwerpunkt der Erklärung liegt auf den „Services” der MVCS-Referenzimplentierung von Robotlegs.

Was sind Services? Services sind zuständig, eine Anwendung mit Daten von externen Quellen zu versorgen. Dies kann z.B. die Anfragen an Datenbanken, das Filesystem, Webservices oder Webseiten-APIs sein. Die externe Anbindung wird also in eine Serviceklasse gekapselt.

Services encapsulate this interaction with external entities, and manage the results, faults, and other events that result from this interaction.

Als Beispiel für einen Service verwende ich die Twitter-Suche, die den aktuellste Tweet mit dem Hashtag #Flash zurückliefert (siehe Tweetr — Twitter-API für Flash).

Robotlegs und Flex Framework

Übrigens: Ich habe dieses Mal das Flex-Framework verwendet. Es wird deutlich, wie sich der Robotlegs-Aufbau eines reinen ActionScript-Projekts (siehe voriger Artikel) ebenso mit einem Flex-Projekt durchführen lässt.

Der einziger wesentliche Unterschied besteht bei meinem Beispiel darin, dass die Hauptdatei (main.mxml) den Context mithilfe von MXML aufruft und die MXML-basierte Viewkomponente (TweetBox) auf der Bühne platziert.
[xml]





[/xml]

Beispiel anschauen

[kml_flashembed publishmethod=“dynamic“ fversion=“10.0.0″ movie=“/wp-content/uploads/2009/12/robotlegs/Main1.swf“ width=“500″ height=“300″ targetclass=“flashmovie“]

Get Adobe Flash player

[/kml_flashembed]

Ablauf

Im Folgenden eine kurze Beschreibung der Abläufe, wenn der Service benutzt wird.

Buttonklick führt Command aus

Beim Klick auf den loadButton in der View wird von der Mediator-Klasse ein Event ausgelöst.

[as]
dispatch(new FlowEvent(FlowEvent.LOAD_LATEST_TWEET))
[/as]

Mapping des Events im Context

Die Zuordnung für dieses Event zum entsprechenden Command mit dem Namen LoadLatestTweet erfolgt im Context. Als Folge wird deshalb LoadLatestTweet ausgeführt.
[as]
commandMap.mapEvent(FlowEvent.LOAD_LATEST_TWEET, LoadLatestTweet);
[/as]

Command ruft Service auf

Die Klasse LoadLatestTweet ruft den Twitter-Service auf, den es injiziert bekommt (mehr zum Inject weiter unten).
[as]
public class LoadLatestTweet extends Command {

[Inject]
public var service:ITwitterService;

public function LoadLatestTweet() {
}

override public function execute():void {
service.getLatestTweet();
}
[/as]

Service liefert Resultat als Event

Der Service sucht nach dem aktuellsten Tweet und liefert das Ergebnis als Payload eines Events.
[as]
var evt:SingleTweetEvent = new SingleTweetEvent(SingleTweetEvent.RESULT);
evt.text = tweet.text;
evt.tweetAge = TweetUtil.returnTweetAge(tweet.createdAt);
evt.userProfileImage = tweet.userProfileImage;
dispatch(evt);
[/as]

Service

Für den Beispiel-Twitter-Service gibt es ein einfaches Interface, ITwitterService. Dieses definiert, dass es die Methode getLatestTweet geben muss.

[as]
public interface ITwitterService {
function getLatestTweet():void;
}
[/as]

Im Beispiel habe ich zwei Klassen, die dieses Interface implementieren: TwitterMockupService und TwitterSearchService. Die erste ist gar kein echter Service, sondern liefert nur Testdaten. Die zweite Klasse nutzt Tweetr und führt eine echte Abfrage durch.

Das Praktische ist nun, dass man bei der Erstellung des Service-Objekts im Context problemlos den tatsächlichen Service wechseln kann (da beide das gleiche Interface implementieren). Auch ein zukünftiger Austausch des Service ist kein Problem, z.B. könnte man auch stattdessen den Twitter-XML-Feed auslesen. Somit hat man eine saubere Trennung des Services vom restlichen Code.

[as]
// Singleton für den Service erstellen
injector.mapSingletonOf(ITwitterService, TwitterSearchService);

// Für Mockup-/Dummycontent stattdessen diese Zeile hier verwenden:
//injector.mapSingletonOf(ITwitterService, TwitterMockupService);
[/as]

Hier das Beispiel mit dem „gefakten” Service.

[kml_flashembed publishmethod=“dynamic“ fversion=“10.0.0″ movie=“/wp-content/uploads/2009/12/robotlegs/Main2.swf“ base=“.“ width=“500″ height=“300″ targetclass=“flashmovie“]

Get Adobe Flash player

[/kml_flashembed]

Wer noch Ergänzungen oder Fragen hat, einfach einen Kommentar hinterlassen.

Download: Quelldateien (.zip)

[ad]

3 Gedanken zu „MVCS: Services in Robotlegs“

  1. ich weiß, dass das beispiel schon etwas älter ist, aber ich bin optimistisch, dass mir doch jemand eine frage beantworten kann:

    angenommen man möchte in dem beispiel mehrere TweetBoxen verwenden, die aber jeweils andere ITwitterService Implementation haben sollen. Wie kann ich differenzieren, welches View-Element mit welchem Command gemappt wird?

    Übrigens, super Tutorial, war sehr verständlich aufbereitet – danke!

  2. Danke.

    Das sollte so gehen:
    injector.mapSingletonOf( ITwitterService, TwitterSearchService, 'name1' );
    injector.mapSingletonOf( ITwitterService, TwitterMockupService, 'name2' );
    Du erstellt also zwei Services. Auf die gleiche Weise könntest du auch 2 Models erstellen.

    Beim Inject greift du dann auf den jeweils gewünschten über den Namen zu:
    [Inject name="name1"]
    public var …

  3. Folgendes klappt bei mir nicht:

    [Inject name="name1"]
    public var service:IFileManagerService;

    Da bekomme ich einen syntax error ?

Schreibe einen Kommentar

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