Menu
Coddy logo textTech

Asynchrone Konstruktoren

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 79 von 110.

Konstruktoren in Dart können nicht als async markiert werden – sie müssen sofort eine Instanz der Klasse zurückgeben, kein Future. Wie erstellt man also Objekte, die eine asynchrone Initialisierung erfordern, wie das Laden von Daten aus einer Datenbank oder das Abrufen von Konfigurationen?

Die Lösung besteht darin, eine statische asynchrone Factory-Methode zu verwenden. Halte den Konstruktor privat (oder einfach) und stelle eine statische Methode bereit, die die asynchrone Arbeit ausführt und ein Future deiner Klasse zurückgibt:

class UserProfile {
  final String name;
  final int age;
  
  UserProfile._(this.name, this.age);  // Privater Konstruktor
  
  static Future<UserProfile> create(String userId) async {
    // Simuliere das Abrufen von Daten
    await Future.delayed(Duration(seconds: 1));
    return UserProfile._('Alice', 25);
  }
}

Future<void> main() async {
  var user = await UserProfile.create('123');
  print(user.name);  // Alice
}

Der private Konstruktor UserProfile._ übernimmt die eigentliche Objekterstellung, während die statische Methode create() die gesamte asynchrone Arbeit übernimmt. Aufrufer verwenden await, um das vollständig initialisierte Objekt zu erhalten.

Dieses Muster stellt sicher, dass Ihr Objekt vollständig einsatzbereit ist, sobald Sie es erhalten – keine teilweise initialisierten Zustände oder fehlenden Daten. Es wird häufig für Klassen verwendet, die Ressourcen laden, Verbindungen zu Diensten herstellen oder eine Einrichtung durchführen müssen, die Zeit in Anspruch nimmt.

challenge icon

Aufgabe

Einfach

Erstellen wir einen Konfigurationslader, der zeigt, wie man die asynchrone Initialisierung in Klassen handhabt! Da Konstruktoren nicht asynchron sein können, verwendest du das Muster der statischen Factory-Methode, um Objekte zu erstellen, deren Daten zunächst „geladen“ werden müssen.

Du organisierst deinen Code in zwei Dateien:

  • config_loader.dart: Erstelle eine ConfigLoader-Klasse, die das asynchrone Laden von Konfigurationseinstellungen simuliert. Deine Klasse sollte Folgendes enthalten:
    • Drei finale Felder: appName (String), version (String) und maxUsers (int)
    • Einen privaten Konstruktor, der alle drei Felder initialisiert
    • Eine statische asynchrone Factory-Methode namens load, die einen String configId-Parameter entgegennimmt und ein Future<ConfigLoader> zurückgibt. Diese Methode sollte:
      • Future.delayed() mit 100 Millisekunden verwenden, um die Ladezeit zu simulieren
      • Die Konfigurationswerte basierend auf configId erzeugen:
        • appName: die configId mit angehängtem " App"
        • version: "1.0.", gefolgt von der Länge von configId
        • maxUsers: die Länge von configId multipliziert mit 10
      • Eine neue ConfigLoader-Instanz mit diesen Werten zurückgeben
    • Eine displayInfo()-Methode, die die Konfiguration in diesem Format ausgibt: Config: [appName] v[version] (max [maxUsers] users)
  • main.dart: Importiere deinen Konfigurationslader und demonstriere das Muster der asynchronen Initialisierung:
    • Loading configurations... ausgeben
    • Eine Konfiguration mit der configId "Production" laden und ihre displayInfo()-Methode aufrufen
    • Eine Konfiguration mit der configId "Dev" laden und ihre displayInfo()-Methode aufrufen
    • All configs loaded! ausgeben

Beachte, wie die statische load-Methode die gesamte asynchrone Arbeit übernimmt, während der private Konstruktor einfach die Werte zuweist. Aufrufer verwenden await, um ein vollständig initialisiertes Objekt zu erhalten!

Erwartete Ausgabe:

Loading configurations...
Config: Production App v1.0.10 (max 100 users)
Config: Dev App v1.0.3 (max 30 users)
All configs loaded!

Probier es selbst

import 'config_loader.dart';

void main() async {
  // TODO: Gebe "Loading configurations..." aus
  
  // TODO: Lade eine Konfiguration mit configId "Production"
  // und rufe deren displayInfo() Methode auf
  
  // TODO: Lade eine Konfiguration mit configId "Dev"
  // und rufe deren displayInfo() Methode auf
  
  // TODO: Gebe "All configs loaded!" aus
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Dart-Compiler