Design Patterns
Entwurfsmuster [4] gehören schon seit Jahren zum Repertoire des professionellen Programmierers. Es überrascht nicht, dass Dart darauf setzt. Das Factory Pattern beispielsweise ist bereits Bestandteil der Sprache: Stellt der Entwickler einem Konstruktor das Schlüsselwort »factory«
voran, erzeugt Dart nicht automatisch selbst ein Objekt dieser Klasse, sondern überlässt das dem Konstruktor. In diesem kann der Programmierer dann beispielsweise in einem Cache nachsehen, ob schon ein passendes Objekt existiert – genau wie in Listing 6: »nocheinauto«
verweist hier auf dasselbe Objekt wie »einauto«
. Aufgrund des Schlüsselworts »static«
existiert »garage«
nur ein einziges Mal, alle »Auto«
-Objekte greifen auf dieselbe Variable zu.
Listing 6
Factory Pattern
01 class Auto {
02 String gefertigtvon;
03 static Map garage;
04
05 factory Auto(String hersteller) {
06 if(Auto.garage == null) Auto.garage=new Map();
07
08 if(Auto.garage.containsKey(hersteller)!=null) return Auto.garage[hersteller];
09 else {
10 Auto neuesauto = new Auto.kaufen(hersteller);
11 Auto.garage[hersteller] = neuesauto;
12 return neuesauto;
13 }
14 }
15
16 Auto.kaufen(this.gefertigtvon);
17 }
18
19 main() {
20 var einauto = new Auto("Ferrari");
21 var nocheinauto = new Auto("Ferrari");
22 }
Das Factory Pattern lässt sich zudem noch mit Interfaces kombinieren. Dazu weist der Programmierer einem Interface eine Standard-Factory-Klasse zu, die wiederum zum Interface passende Objekte zurückliefert. Listing 7 zeigt dazu ein Beispiel. Das Interface legt dabei die Signatur des Konstruktors fest, der dann zum Interface passende Objekte ausgibt. Die »AutoFabrik«
liefert abhängig vom ihr übergebenen »hersteller«
entweder ein »Rennwagen«
- oder ein »Mittelklasse«
-Objekt. Bei der Instanzierung in »main()«
sieht es dann so aus, als würde man direkt ein »Auto«
anlegen.
Listing 7
Kombination von interface und factory
01 interface Auto default AutoFabrik {
02 Auto(hersteller);
03 final hersteller;
04 }
05
06 class AutoFabrik {
07 factory Auto(hersteller) {
08 if (hersteller == "Ferrari") {
09 return new Rennwagen(hersteller);
10 }
11 return new Mittelklasse(hersteller);
12 }
13 }
14
15 class Rennwagen implements Auto {
16 Rennwagen(this.hersteller);
17 String hersteller;
18 }
19
20 class Mittelklasse implements Auto {
21 Mittelklasse(this.hersteller);
22 String hersteller;
23 }
24
25 main() {
26 print(new Auto("Ferrari") is Rennwagen);
27 print(new Auto("VW") is Rennwagen);
28 }
Wie in Listing 7 ebenfalls zu sehen ist, prüft das Schlüsselwort »is«
, ob ein Objekt von einem bestimmten Typ ist. Das Schlüsselwort »final«
vor »hersteller«
sorgt übrigens dafür, dass sich der Variablen nur genau einmal bei ihrer Initialisierung ein Wert zuweisen lässt.
Dart enthält die aus Java bekannten generischen Typen alias Generics. C++-Programmierer kennen das Konzept als Templates. Mit ihnen lassen sich schnell Container für beliebige Objekte schaffen. Die eingebauten Listen und Maps sind bereits von Haus aus generische Typen. So erzeugt etwa »List<Auto>«
eine Liste für Auto-Objekte (Listing 8).
Listing 8
Generische Typen
01 main() {
02 List<Auto> autoliste = new List<Auto>();
03 autoliste.add(new Auto("Ferrari"));
04 Auto einauto = autoliste[0];
05 }
Da Variablen beliebige Inhalte aufnehmen, sperrt sich Dart allerdings auch nicht gegen Folgendes:
List<Auto> autoliste = new List<Auto>(); List<LKW> lkwliste = autoliste;
Dieser Versuch fliegt dem Entwickler aber später vielleicht um die Ohren, wenn er etwas mit den vermeintlichen LKWs aus der »lkwliste«
anstellen möchte.
Nebenläufigkeit
Parallel zu erledigende Aufgaben lagert der Programmierer normalerweise in je einen separaten Thread aus und versucht mit viel Hirnschmalz und Verwaltungsaufwand deren Zwischenergebnisse zusammenzuführen. Dem nimmt Dart den Schrecken: Ein von der Basisklasse »Isolate«
abgeleitetes Objekt läuft auf Wunsch isoliert neben dem Hauptprogramm in einem eigenen Thread.
Um miteinander Zwischenergebnisse auszutauschen, können sich solche Isolates gegenseitig Nachrichten schicken. Die landen zunächst in einer Warteschlange, bis sie das empfangende Isolate über einen so genannten Port abholt. Dieses Konzept lehnt sich stark an das Aktoren-Modell aus Erlang beziehungsweise Scala an. Listing 9 zeigt ein komplettes Beispiel dafür.
Listing 9
Kommunikation mit einem Isolate
01 class Empfaenger extends Isolate {
02 main() {
03 port.receive((nachricht, replyTo) {
04 if (nachricht == null) port.close();
05 else print("Empfange: ${nachricht}");
06 });
07 }
08 }
09
10 main() {
11 new Empfaenger().spawn().then((port) {
12 for (var nachricht in ['Dies', 'ist', 'ein', 'Test']) {
13 port.send(nachricht);
14 }
15 port.send(null);
16 });
17 }
Zunächst erstellt das Beispielprogramm ein neues »Empfaenger«
-Objekt, das es via »spawn()«
in einen eigenen Thread verfrachtet. Anschließend sendet es dem Objekt nacheinander vier Wörter. Sobald das Objekt ein Wort empfängt, schreibt es dieses auf den Bildschirm. Das Isolate bekommt übrigens mit »replyTo«
immer einen Port zum Objekt übergeben, das ihm die Nachricht geschickt hat. Damit kann es dann direkt seinem Auftraggeber antworten.
Isolates laufen in getrennten Speicherbereichen. Das hat den angenehmen Nebeneffekt, dass die Garbage Collection jedes Isolate individuell behandeln kann. Im Gegenzug muss die virtuelle Maschine die Nachrichten zwischen den Isolates kopieren. Künftig sollen Isolates sogar unterschiedliche Dart-Bibliotheken in verschiedenen Versionen nutzen können.
Diesen Artikel als PDF kaufen
Express-Kauf als PDF
Umfang: 5 Heftseiten
Preis € 0,99
(inkl. 19% MwSt.)
Als digitales Abo
Weitere Produkte im Medialinx Shop »
Versandartikel
Onlineartikel
Alle Rezensionen aus dem Linux-Magazin
- Buecher/07 Bücher über 3-D-Programmierung sowie die Sprache Dart
- Buecher/06 Bücher über Map-Reduce und über die Sprache Erlang
- Buecher/05 Bücher über Scala und über Suchmaschinen-Optimierung
- Buecher/04 Bücher über Metasploit sowie über Erlang/OTP
- Buecher/03 Bücher über die LPI-Level-2-Zertifizierung
- Buecher/02 Bücher über Node.js und über nebenläufige Programmierung
- Buecher/01 Bücher über Linux-HA sowie über PHP-Webprogrammierung
- Buecher/12 Bücher über HTML-5-Apps sowie Computer Vision mit Python
- Buecher/11 Bücher über Statistik sowie über C++-Metaprogrammierung
- Buecher/10 Bücher zu PHP-Webbots sowie zur Emacs-Programmierung
Insecurity Bulletin
Im Insecurity Bulletin widmet sich Mark Vogelsberger aktuellen Sicherheitslücken sowie Hintergründen und Security-Grundlagen. mehr...





