Menu
Coddy logo textTech

Konstruktory asynchroniczne

Część sekcji Programowanie obiektowe ścieżki Dart w Coddy. Lekcja 79 z 110.

Konstruktorów w Dart nie można oznaczyć jako async — muszą natychmiast zwracać instancję klasy, a nie Future. Jak więc tworzyć obiekty, które wymagają asynchronicznej inicjalizacji, takiej jak wczytywanie danych z bazy danych lub pobieranie konfiguracji?

Rozwiązaniem jest użycie statycznej asynchronicznej metody fabrykującej. Pozostaw konstruktor prywatny (lub prosty) i udostępnij metodę statyczną, która wykonuje operację asynchroniczną i zwraca Future Twojej klasy:

class UserProfile {
  final String name;
  final int age;
  
  UserProfile._(this.name, this.age);  // Konstruktor prywatny
  
  static Future<UserProfile> create(String userId) async {
    // Symuluj pobieranie danych
    await Future.delayed(Duration(seconds: 1));
    return UserProfile._('Alice', 25);
  }
}

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

Prywatny konstruktor UserProfile._ odpowiada za faktyczne tworzenie obiektu, a statyczna metoda create() obsługuje całą pracę asynchroniczną. Wywołujący używają await, aby otrzymać w pełni zainicjalizowany obiekt.

Ten wzorzec zapewnia, że obiekt jest całkowicie gotowy do użycia, gdy tylko go otrzymasz — nie ma stanów częściowej inicjalizacji ani brakujących danych. Jest powszechnie stosowany w klasach, które muszą wczytywać zasoby, łączyć się z usługami lub wykonywać konfigurację wymagającą czasu.

challenge icon

Wyzwanie

Łatwy

Zbudujmy moduł ładujący konfigurację, który pokaże, jak obsługiwać asynchroniczną inicjalizację w klasach! Ponieważ konstruktory nie mogą być asynchroniczne, użyjesz wzorca statycznej metody fabrykującej do tworzenia obiektów, których dane wymagają czasu, aby się „załadować”.

Podzielisz kod na dwa pliki:

  • config_loader.dart: Utwórz klasę ConfigLoader, która symuluje asynchroniczne ładowanie ustawień konfiguracji. Twoja klasa powinna mieć:
    • Trzy pola final: appName (String), version (String) i maxUsers (int)
    • Prywatny konstruktor, który inicjalizuje wszystkie trzy pola
    • Statyczną asynchroniczną metodę fabrykującą o nazwie load, która przyjmuje parametr String configId i zwraca Future<ConfigLoader>. Ta metoda powinna:
      • Użyć Future.delayed() z opóźnieniem 100 milisekund, aby zasymulować czas ładowania
      • Wygenerować wartości konfiguracji na podstawie configId:
        • appName: configId z dopisanym " App"
        • version: "1.0.", po którym następuje długość configId
        • maxUsers: długość configId pomnożona przez 10
      • Zwrócić nową instancję ConfigLoader z tymi wartościami
    • Metodę displayInfo(), która wyświetla konfigurację w tym formacie: Config: [appName] v[version] (max [maxUsers] users)
  • main.dart: Zaimportuj moduł ładujący konfigurację i pokaż wzorzec asynchronicznej inicjalizacji:
    • Wyświetl Loading configurations...
    • Załaduj konfigurację z configId "Production" i wywołaj jej displayInfo()
    • Załaduj konfigurację z configId "Dev" i wywołaj jej displayInfo()
    • Wyświetl All configs loaded!

Zwróć uwagę, jak statyczna metoda load obsługuje całą pracę asynchroniczną, podczas gdy prywatny konstruktor po prostu przypisuje wartości. Wywołujący używają await, aby uzyskać w pełni zainicjalizowany obiekt!

Oczekiwany wynik:

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

Spróbuj swoich sił

import 'config_loader.dart';

void main() async {
  // TODO: Wypisz "Loading configurations..."
  
  // TODO: Wczytaj konfigurację z configId "Production"
  // i wywołaj jej metodę displayInfo()
  
  // TODO: Wczytaj konfigurację z configId "Dev"
  // i wywołaj jej metodę displayInfo()
  
  // TODO: Wypisz "All configs loaded!"
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Dart online