Menu
Coddy logo textTech

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.

challenge icon

Défi

Facile

Construisons un chargeur de configuration qui dé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 de fabrique statique (static factory method pattern) 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 classe ConfigLoader qui simule le chargement de paramètres de configuration de manière asynchrone. Votre classe doit avoir :
    • Trois champs finaux : appName (String), version (String), et maxUsers (int)
    • Un constructeur privé qui initialise les trois champs
    • Une méthode de fabrique statique asynchrone appelée load qui prend un paramètre String configId et retourne un Future<ConfigLoader>. Cette méthode doit :
      • Utiliser Future.delayed() avec 100 millisecondes pour simuler le temps de chargement
      • Générer les valeurs de configuration basées sur le configId :
        • appName : le configId avec " App" ajouté à la fin
        • version : "1.0." suivi de la longueur de configId
        • maxUsers : la longueur de configId multipliée par 10
      • Retourner une nouvelle instance de ConfigLoader avec ces valeurs
    • Une méthode displayInfo() qui affiche la configuration dans ce format : Config: [appName] v[version] (max [maxUsers] users)
  • main.dart : Importez votre chargeur de configuration et démontrez le modèle d'initialisation asynchrone :
    • Affichez Loading configurations...
    • Chargez une configuration avec le configId "Production" et appelez sa méthode displayInfo()
    • Chargez une configuration avec le configId "Dev" et appelez sa méthode displayInfo()
    • Affichez All configs loaded!

Remarquez comment la méthode statique load gère tout le travail asynchrone, tandis que le constructeur privé se contente d'assigner 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!

Aide-mémoire

Les constructeurs en Dart ne peuvent pas être marqués comme async car ils doivent retourner immédiatement une instance de la classe, et non un Future.

Pour créer des objets nécessitant une initialisation asynchrone, utilisez une méthode factory statique asynchrone :

class UserProfile {
  final String name;
  final int age;
  
  UserProfile._(this.name, this.age);  // Private constructor
  
  static Future<UserProfile> create(String userId) async {
    // Perform async work here
    await Future.delayed(Duration(seconds: 1));
    return UserProfile._('Alice', 25);
  }
}

Utilisation :

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

Le constructeur privé (marqué par _) gère la création de l'objet, tandis que la méthode statique gère le travail asynchrone. Cela garantit que les objets sont entièrement initialisés avant leur utilisation.

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!"
}
quiz iconTestez-vous

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