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.
Wyzwanie
ŁatwyZbudujmy 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) imaxUsers(int) - Prywatny konstruktor, który inicjalizuje wszystkie trzy pola
- Statyczną asynchroniczną metodę fabrykującą o nazwie
load, która przyjmuje parametrString configIdi zwracaFuture<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ść configIdmaxUsers: długość configId pomnożona przez 10
- Zwrócić nową instancję
ConfigLoaderz tymi wartościami
- Użyć
- Metodę
displayInfo(), która wyświetla konfigurację w tym formacie:Config: [appName] v[version] (max [maxUsers] users)
- Trzy pola final:
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 jejdisplayInfo() - Załaduj konfigurację z configId
"Dev"i wywołaj jejdisplayInfo() - Wyświetl
All configs loaded!
- Wyświetl
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!"
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy OOP
Pliki zewnętrzneBiblioteki i importyWprowadzenie do OOPKlasy a obiektySłowo kluczowe thisMetodyZmienne instancjiPodstawy konstruktorówPowtórka – prosty kalkulator4Bezpieczeństwo wartości null
Wprowadzenie do bezpieczeństwa wartości nullTypy dopuszczające null i niedopuszczające nullOperatory ? i !Słowo kluczowe late a bezpieczeństwo wartości nullOperatory uwzględniające nullBezpieczeństwo wartości null w klasachPodsumowanie — system profili użytkowników7Klasy abstrakcyjne i interfejsy
Klasy abstrakcyjneMetody abstrakcyjneInterfejsy w DartInterfejsy niejawneImplementowanie a rozszerzanieWiele interfejsówPowtórka — kalkulator kształtów10Kolekcje i typy generyczne
Przegląd List, Set i MapKolekcje bezpieczne typowoKlasy generyczneMetody generyczneOgraniczenia typów generycznychIterable i IteratorPowtórka — generyczne przechowywanie danych13Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieMetody rozszerzająceKlasy wywoływalneKlasy zapieczętowane (Dart 3)Rekordy (Dart 3)Wzorce i dopasowywanie (3.0)Typy wyliczeniowe z metodami16Projekt: Zarządzanie biblioteką
Omówienie projektuKlasy książek i użytkowników2Konstruktory w Dart
Konstruktor domyślnyKonstruktory nazwaneListy inicjalizująceKonstruktory stałeKonstruktory fabryczneKonstruktory przekierowującePodsumowanie — budowanie kształtów5Hermetyzacja
Elementy publiczne a prywatneKonwencja prefiksu _Prywatność na poziomie bibliotekiGettery i settery — szczegółowoUkrywanie informacjiPodsumowanie — dane uczniów8Domieszki
Wprowadzenie do domieszekTworzenie domieszekKorzystanie z wielu domieszekSłowo kluczowe on w domieszkachDomieszka a dziedziczenieDomieszka a interfejsPodsumowanie – system zwierząt11Metody specjalne
Nadpisanie toString()Nadpisanie hashCode i ==Interfejs ComparableMetoda call()Nadpisanie noSuchMethodPodsumowanie — własna kolekcja14Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec Strategy3Właściwości klas
Elementy instancji a elementy statycznePola final i constZmienne inicjalizowane z opóźnieniemMetody i pola statyczneGettery i setteryPowtórzenie – menedżer kont bankowych6Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe superPrzesłanianie metodAdnotacja @overrideSłowo kluczowe final dla klasKonstruktory i dziedziczeniePowtórzenie – hierarchia pracowników9Polimorfizm
Podstawy polimorfizmuPolimorfizm za pomocą interfejsówSprawdzanie typu w czasie działaniaOperatory is i asSłowo kluczowe covariantPodsumowanie — procesor płatności12Asynchroniczne OOP
Futures i async/awaitPodstawy strumieniKontrolery strumieniKonstruktory asynchroniczneAsynchroniczność w metodach klasyPodsumowanie — pobieranie danychPoćwicz samodzielnie: Kompilator Dart online