Builder Design Pattern zum Parsen von XML-Daten

Bei der Lektüre von Flash Engineering bin ich auf das Erzeugungsmuster „Erbauer (Builder)” gestoßen. Dieses Erzeugungsmuster ist dazu gedacht, einem bei der Erstellung von Objekten zu helfen.

Da das Pattern z.B. für das Parsen von XML-Daten äußerst hilfreich zu sein scheint, habe ich eine Beispiel dazu erstellt. Die Theorie erspare ich mir, siehe dazu z.B. Erbauer Entwurfsmuster (Wikipedia) oder ActionScript 3.0 Builder Design Pattern Part I: Controlling Creation

Ausgangslage

Als Ausgangslage habe ich XML-Daten (z.B. einen RSS-Feed).
[xml]


My first post


What’s up?


The story continues…


[/xml]
Aus diesen Daten sollen nun konkrete Objekte (eine Artikelliste und eine Tagcloud) erzeugt werden. Die Idee des Patterns liegt darin, diese Aufgabe in zwei Teilen zu trennen:

  • das Parsen der XML-Daten
  • das Erzeugen der Objekte

Der Vorteil: Ändern sich die XML-Daten, müsste nur der Parser angepasst werden. Würden sich die Objekte ändern oder werden neue Objekte gewünscht, ist lediglich eine Anpassung im Erzeuger (Builder) bzw. ein neuer Erzeuger notwendig.

Hauptklasse (Client)

Die Hauptklasse ruft den FeedParser auf. Neben den XML-Daten wird ein konkreter Erzeuger übermittelt (z.B. articleListBuilder), der das gewünschte Objekt bauen soll.

[as]
package {
import flash.display.Sprite;

public class Main extends Sprite {

private var xmlParser:FeedParser; // Xml Parser
private var articleListBuilder:ArticleListBuilder = new ArticleListBuilder(); // Concrete Builder
private var tagCloudBuilder:TagCloudBuilder = new TagCloudBuilder(); // Concrete Builder

public function Main() {
getMyArticles();
getMyTagCloud();
}

private function getMyArticles():void {
// Initialize the parser with XML data and the concrete builder
xmlParser = new FeedParser(getXmlData(), articleListBuilder);

// start parsing
xmlParser.parse();

// get the ArticleListe object from the builder
var myArticleList:ArticleList = articleListBuilder.getArticleList();

// just trace it…
trace(myArticleList.getCurrentArticles());
}

private function getMyTagCloud() : void {
// Initialize the parser with XML data and the concrete builder
xmlParser = new FeedParser(getXmlData(), tagCloudBuilder);

// start parsing
xmlParser.parse();

// get the TagCloud object from the builder
var myTagCloud:TagCloud = tagCloudBuilder.getTagCloud();

// just trace it…
trace(myTagCloud.getCurrentTags());
}

// Just setup some dummy xml data
private function getXmlData():XML {
var xmlString:String =
My first postWhat’s up?The story continues…„;
return new XML(xmlString);
}
}
}
[/as]

Feed parsen

Der Parser (allgemein Direktor genannt im Erzeuger-Pattern) kennt die XML-Struktur und liest die Werte lediglich aus. Diese werden an den Erzeuger „in Rohform“ übergeben.
[as]
package {

/**
* The parser knows the XML structure and submits the data to the builder
*/
public class FeedParser {

private var xmlData:XML;
private var builder:IXmlBuilder;

public function FeedParser(xml:XML, builderObj:IXmlBuilder) {
xmlData = xml; // save the data
builder = builderObj; // save the data
}

public function parse():void {
// loop through the items in the xml data
for each (var node:XML in xmlData.item) {

// call the builder with the value from xml
builder.buildHeadline(node.headline.text() );

// call the builder with the value from xml
builder.buildTag(node.@tag);
}

}
}
}
[/as]

Objekt erzeugen (Builder)

Mit den Daten vom Parser erstellt der Builder das tatsächlich Objekt (in diesem Fall die Artikelliste).

Wichtig: Er implementiert ein Interface (IXmlBuilder). Dieses Interface legt quasi fest, welche Informationen der Parser in den XML-Daten erkennen kann.

[as]
package {

/**
* This Builder receives the data and creates the article list
*/
public class ArticleListBuilder implements IXmlBuilder {

private var _articleList:ArticleList = new ArticleList();

public function buildHeadline(text:String):void {
_articleList.addArticle(text);
}

public function buildTag(text:String):void {
}

public function getArticleList():ArticleList {
return _articleList;
}
}
}

[/as]
Nach dem nun das Objekt erstellt wurde, kann man aus dem Klienten die Artikelliste mit articleListBuilder.getArticleList(); abholen.

Quellcode

Den Quellcode des Projekts gibt es hier zum Download: Sourcecode (.zip)

Noch Verbesserungsvorschläge oder Anmerkungen?

[ad]

Schreibe einen Kommentar

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