Constructeurs asynchrones
Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy. Leçon 79 sur 110.
Les constructeurs en Dart ne peuvent pas être marqués comme async - ils doivent retourner une instance de la classe immédiatement, et non un Future. Alors, comment créer des objets qui nécessitent une initialisation asynchrone, comme le chargement de données depuis une base de données ou la récupération d'une configuration ?
La solution consiste à utiliser une méthode de fabrique statique asynchrone. Gardez le constructeur privé (ou simple) et fournissez une méthode statique qui effectue le travail asynchrone et renvoie un Future de votre classe :
class UserProfile {
final String name;
final int age;
UserProfile._(this.name, this.age); // Constructeur privé
static Future<UserProfile> create(String userId) async {
// Simuler la récupération de données
await Future.delayed(Duration(seconds: 1));
return UserProfile._('Alice', 25);
}
}
Future<void> main() async {
var user = await UserProfile.create('123');
print(user.name); // Alice
}Le constructeur privé UserProfile._ gère la création réelle de l'objet, tandis que la méthode statique create() gère tout le travail asynchrone. Les appelants utilisent await pour obtenir l'objet entièrement initialisé.
Ce patron garantit que votre objet est complètement prêt à l'emploi une fois que vous l'avez - pas d'états partiellement initialisés ou de données manquantes. Il est couramment utilisé pour les classes qui doivent charger des ressources, se connecter à des services ou effectuer toute configuration qui prend du temps.
Défi
FacileConstruisons un chargeur de configuration qui montre comment gérer l'initialisation asynchrone dans les classes ! Comme les constructeurs ne peuvent pas être asynchrones, vous utiliserez le modèle de méthode fabrique statique pour créer des objets qui ont besoin de temps pour « charger » leurs données.
Vous organiserez votre code en deux fichiers :
config_loader.dart: créez une classeConfigLoaderqui simule le chargement asynchrone des paramètres de configuration. Votre classe doit comporter :- Trois champs finaux :
appName(String),version(String) etmaxUsers(int) - Un constructeur privé qui initialise les trois champs
- Une méthode fabrique statique asynchrone appelée
loadqui accepte un paramètreString configIdet renvoie unFuture<ConfigLoader>. Cette méthode doit :- Utiliser
Future.delayed()avec 100 millisecondes pour simuler le temps de chargement - Générer les valeurs de configuration en fonction de
configId:appName: configId auquel" App"est ajoutéversion:"1.0."suivi de la longueur de configIdmaxUsers: la longueur de configId multipliée par 10
- Renvoyer une nouvelle instance de
ConfigLoaderavec ces valeurs
- Utiliser
- Une méthode
displayInfo()qui affiche la configuration dans ce format :Config: [appName] v[version] (max [maxUsers] users)
- Trois champs finaux :
main.dart: importez votre chargeur de configuration et présentez le modèle d'initialisation asynchrone :- Afficher
Loading configurations... - Charger une configuration avec l'identifiant configId
"Production"et appeler sa méthodedisplayInfo() - Charger une configuration avec l'identifiant configId
"Dev"et appeler sa méthodedisplayInfo() - Afficher
All configs loaded!
- Afficher
Remarquez comment la méthode statique load gère tout le travail asynchrone, tandis que le constructeur privé se contente d'affecter les valeurs. Les appelants utilisent await pour obtenir un objet entièrement initialisé !
Sortie attendue :
Loading configurations...
Config: Production App v1.0.10 (max 100 users)
Config: Dev App v1.0.3 (max 30 users)
All configs loaded!Essayez vous-même
import 'config_loader.dart';
void main() async {
// TODO: Afficher "Loading configurations..."
// TODO: Charger une configuration avec le configId "Production"
// et appeler sa méthode displayInfo()
// TODO: Charger une configuration avec le configId "Dev"
// et appeler sa méthode displayInfo()
// TODO: Afficher "All configs loaded!"
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBibliothèques et importsIntroduction à la POOClasses vs objetsLe mot-clé thisMéthodesVariables d’instanceBases des constructeursRécapitulatif - Calculatrice simple4Sécurité face aux valeurs nulles
Introduction à la sécurité face aux valeurs nullesNullable vs Non-NullableLes opérateurs ? et !Mot-clé Late et sécurité face aux valeurs nullesOpérateurs sensibles à nullSécurité face aux valeurs nulles dans les classesRécapitulatif – Système de profil utilisateur7Classes abstraites et interfaces
Classes abstraitesMéthodes abstraitesInterfaces en DartInterfaces implicitesImplémenter ou étendreInterfaces multiplesRécapitulatif - Calculateur de formes10Collections et génériques
Vue d’ensemble des List, Set et MapCollections à typage sûrClasses génériquesMéthodes génériquesContraintes génériquesIterable et IteratorRécapitulatif – stockage générique2Constructeurs en Dart
Constructeur par défautConstructeurs nommésListes d'initialisationConstructeurs constantsConstructeurs factoryConstructeurs redirigésRécapitulatif - Constructeur de formes5Encapsulation
Membres publics vs privésLa convention du préfixe _Confidentialité au niveau de la bibliothèqueApprofondissement des getters et settersMasquage de l’informationRécapitulatif - Fiches des étudiants8Mixins
Introduction aux MixinsCréer des MixinsUtiliser plusieurs MixinsMot-clé on dans les MixinsMixin ou héritageMixin ou interfaceRécapitulatif - Système animal11Méthodes spéciales
Redéfinition de toString()Redéfinition de hashCode et ==Interface ComparableMéthode call()Redéfinition de noSuchMethodRécapitulatif - Collection personnalisée14Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy3Propriétés des classes
Membres d’instance et statiquesChamps Final et ConstVariables différéesMéthodes et champs statiquesAccesseurs et mutateursRécapitulatif - Gestionnaire de compte bancaire6Héritage
Héritage de baseLe mot-clé superRedéfinition de méthodeL’annotation @overrideLe mot-clé de classe finalConstructeurs et héritageRécapitulatif – Hiérarchie des employés9Polymorphisme
Bases du polymorphismePolymorphisme via les interfacesVérification des types à l’exécutionLes opérateurs is et asMot-clé covariantRécapitulatif - Processeur de paiements12POO asynchrone
Futures et async/awaitNotions de base des StreamsContrôleurs de StreamsConstructeurs asynchronesAsynchrone dans les méthodes de classeRécapitulatif - récupérateur de données15Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron DépôtEntraînez-vous par vous-même : Compilateur Dart en ligne