5.2 Fonction Factory
Dans la vidéo précédente, vous avez appris à utiliser la syntaxe littérale pour créer un objet. Cette approche pose toutefois un problème dès qu'il faut créer plusieurs instances d'un même type. Imaginez qu'on duplique notre objet circle pour en avoir deux : on duplique aussi l'implémentation de chaque méthode. Si la méthode contenait dix lignes de code et qu'un bug s'y glissait, il faudrait le corriger à plusieurs endroits.
Quand un objet contient de la logique, on a donc besoin d'un mécanisme de fabrication. Deux patterns existent en JavaScript : les factory functions et les fonctions constructeur. Voyons d'abord les factory functions.
Définir une factory function
Comme son nom l'indique, une factory function est une fonction qui « fabrique » et retourne un nouvel objet. On déplace simplement la définition de l'objet à l'intérieur de la fonction, on paramètre les valeurs variables, et on retourne l'objet créé.
function createCircle(radius) {
return {
radius,
draw() {
console.log('draw');
}
};
}
const circle1 = createCircle(1);
const circle2 = createCircle(2);
circle1.draw();
Les sucres syntaxiques d'ES6
Le code ci-dessus utilise deux raccourcis introduits par ES6. Quand une clé d'objet porte le même nom que la valeur (variable) qu'on lui assigne, on peut omettre la duplication : { radius } au lieu de { radius: radius }. Pour les méthodes, on peut aussi omettre le mot-clé function et la paire clé: function(), et écrire directement draw() { ... }.
Le gros avantage du pattern factory, c'est que la logique de la méthode draw est définie à un seul endroit. Si un bug apparaît, vous le corrigez à un seul endroit et tous les cercles bénéficient automatiquement de la correction. C'est l'un des bénéfices fondamentaux de l'encapsulation par fonction.
Mais les factory functions ne sont pas le seul moyen de créer des objets en JavaScript. La prochaine vidéo couvre les fonctions constructeur, qui résolvent le même problème avec une approche un peu différente — notamment en utilisant this et l'opérateur new.
En résumé
Les factory fonctions sont des fonctions qui produisent des objets, permettant de résoudre la duplication de code lors de la création de plusieurs objets similaires. Plutôt que de répéter la définition de l'objet, on centralise la logique dans une seule fonction qui prend en paramètre les valeurs nécessaires (comme le rayon pour un cercle) et retourne l'objet configuré. L'avantage principal est que toute correction de bug n'a besoin d'être effectuée qu'en un seul endroit.
Points clés
- Les factory fonctions résolvent le problème de duplication de code en centralisant la création d'objets
- Une factory fonction accepte des paramètres et retourne un nouvel objet configurable (exemple : createCercle(rayon))
- La syntaxe ES6 moderne raccourcit le code : shorthand pour les propriétés identiques au paramètre et syntaxe abrégée pour les méthodes
- Chaque appel de factory fonction crée un nouvel objet indépendant avec les valeurs différentes passées en paramètres
- La logique du code (notamment les méthodes) est définie une seule fois, facilitant la maintenance et les corrections de bugs
- Les factory fonctions ne sont pas l'unique approche pour créer des objets; les fonctions constructeur offrent une alternative
Questions fréquentes
Quel est le principal problème résolu par les factory fonctions ?
La duplication de code. Sans factory fonction, si vous voulez créer plusieurs objets similaires (deux cercles), vous devez copier-coller toute la définition de l'objet, ce qui rend la maintenance difficile. Avec une factory fonction, la logique est définie une seule fois.
Comment crée-t-on différents objets avec une factory fonction ?
En appelant la factory fonction plusieurs fois avec des paramètres différents. Par exemple, createCercle(1) crée un cercle de rayon 1, et createCercle(2) crée un cercle de rayon 2. Chaque appel produit un nouvel objet indépendant.
Qu'est-ce que la syntaxe raccourcie ES6 pour les méthodes dans un objet ?
Au lieu d'écrire 'draw: function() {}', vous pouvez écrire directement 'draw() {}'. C'est équivalent mais plus concis et lisible.