Les décorateurs et le renvoi (ou transmission) sont deux concepts importants en programmation JavaScript qui permettent d’améliorer la modularité, la réutilisabilité et la lisibilité du code. Commençons par discuter des décorateurs, puis nous aborderons le renvoi.
Les Decorators (Décorateurs)
Les décorateurs sont une fonctionnalité de programmation qui permet d’ajouter du comportement à une fonction ou à une classe existante de manière déclarative. Ils sont largement utilisés dans les langages de programmation modernes comme JavaScript pour des tâches telles que la journalisation, la validation des données, la gestion des autorisations, etc.

En JavaScript, les décorateurs peuvent être implémentés en utilisant des fonctions de haut niveau qui prennent une fonction ou une classe comme argument, et renvoient généralement une nouvelle fonction ou classe enrichie de fonctionnalités supplémentaires.
Par exemple, considérons un décorateur de journalisation simple qui enregistre les appels à une fonction avec leurs arguments et leurs valeurs de retour :
javascriptfunction log(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
console.log(`Calling ${name} with args: ${args}`);
const result = original.apply(this, args);
console.log(`Function ${name} returned: ${result}`);
return result;
};
return descriptor;
}
class Calculator {
@log
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
calc.add(1, 2); // Output: Calling add with args: 1,2
// Function add returned: 3
Dans cet exemple, le décorateur @log
est appliqué à la méthode add
de la classe Calculator
. Lorsque la méthode add
est appelée, le décorateur intercepte l’appel, enregistre les arguments passés et la valeur de retour, puis renvoie le résultat de l’appel original.
Le Forwarding (Renvoi ou Transmission)
Le renvoi, également appelé transmission ou délégation, est un mécanisme permettant à un objet d’acheminer (ou de « transmettre ») les appels de méthodes ou les accès à des propriétés à un autre objet associé. Cela permet d’implémenter des relations de composition entre objets plutôt que d’héritage, favorisant ainsi une meilleure modularité et une plus grande flexibilité dans la conception logicielle.
En JavaScript, le renvoi peut être mis en œuvre en définissant des méthodes spéciales dans un objet pour intercepter les appels de méthodes ou les accès à des propriétés. Ces méthodes spéciales sont généralement appelées « handlers ».
Par exemple, considérons un objet proxy
qui renvoie toutes les méthodes et propriétés à un autre objet target
associé :
javascriptconst target = {
message: "Hello",
greet() {
return this.message;
}
};
const handler = {
get(target, prop) {
if (prop in target) {
return target[prop];
} else {
return `Property '${prop}' not found`;
}
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // Output: Hello
console.log(proxy.greet()); // Output: Hello
console.log(proxy.unknownProperty); // Output: Property 'unknownProperty' not found
Dans cet exemple, nous créons un objet proxy
qui renvoie toutes les propriétés et méthodes à l’objet target
associé. Lorsque nous accédons à une propriété ou appelons une méthode sur proxy
, le handler get
est déclenché et renvoie la propriété correspondante de target
ou un message d’erreur si la propriété n’existe pas.
Conclusion
En résumé, les décorateurs et le renvoi sont deux mécanismes puissants en JavaScript pour améliorer la modularité, la réutilisabilité et la lisibilité du code. Les décorateurs permettent d’ajouter du comportement à des fonctions ou des classes existantes de manière déclarative, tandis que le renvoi permet à un objet de déléguer les appels de méthodes ou les accès à des propriétés à un autre objet associé. En combinant ces deux techniques, les développeurs peuvent créer des architectures logicielles plus flexibles et maintenables.
Plus de connaissances
Bien sûr, approfondissons davantage ces concepts.
Les Decorators (Décorateurs)
Les décorateurs offrent une manière élégante d’ajouter des fonctionnalités à des classes et à leurs membres dans JavaScript. Ils sont largement utilisés dans les bibliothèques et les frameworks modernes tels que React, Angular et Vue.js pour ajouter des fonctionnalités telles que l’injection de dépendances, la validation des données, la gestion des autorisations, etc.
Dans JavaScript, les décorateurs peuvent être implémentés de différentes manières. Une approche courante est d’utiliser des fonctions de haut niveau qui prennent une fonction ou une classe comme argument et renvoient généralement une nouvelle fonction ou classe enrichie de fonctionnalités supplémentaires. Ces fonctions de haut niveau peuvent être utilisées comme des annotations avant une fonction ou une classe, ce qui les rend facilement identifiables dans le code.
Par exemple, considérons un exemple de validation de données à l’aide de décorateurs :
javascriptfunction validate(target, name, descriptor) {
const original = descriptor.value;
descriptor.value = function(...args) {
for (let arg of args) {
if (typeof arg !== 'number') {
throw new Error(`Parameter ${arg} is not a number`);
}
}
return original.apply(this, args);
};
return descriptor;
}
class Calculator {
@validate
add(a, b) {
return a + b;
}
}
const calc = new Calculator();
calc.add(1, 2); // Output: 3
calc.add("1", 2); // Throws error: Parameter 1 is not a number
Dans cet exemple, le décorateur @validate
est appliqué à la méthode add
de la classe Calculator
. Avant d’appeler la méthode add
, le décorateur vérifie que tous les arguments sont de type nombre. Si l’un des arguments n’est pas un nombre, une erreur est levée.
Le Forwarding (Renvoi ou Transmission)
Le renvoi, également connu sous le nom de transmission ou de délégation, est un concept fondamental en programmation qui permet à un objet d’acheminer (ou de « transmettre ») les appels de méthodes ou les accès à des propriétés à un autre objet associé. Cela permet d’implémenter des relations de composition entre objets plutôt que d’héritage, ce qui favorise une meilleure modularité et une plus grande flexibilité dans la conception logicielle.
En JavaScript, le renvoi est souvent mis en œuvre à l’aide du patron de conception du proxy. Un proxy est un objet qui agit comme une interface vers un autre objet, appelé objet cible. Lorsqu’une méthode est appelée ou qu’une propriété est accédée sur le proxy, le comportement est intercepté par un gestionnaire (handler), qui peut ensuite décider de renvoyer les appels à l’objet cible ou d’effectuer d’autres actions.
Voici un exemple de renvoi en utilisant un proxy :
javascriptconst target = {
message: "Hello",
greet() {
return this.message;
}
};
const handler = {
get(target, prop) {
if (prop in target) {
return target[prop];
} else {
return `Property '${prop}' not found`;
}
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // Output: Hello
console.log(proxy.greet()); // Output: Hello
console.log(proxy.unknownProperty); // Output: Property 'unknownProperty' not found
Dans cet exemple, un objet proxy
est créé pour l’objet target
. Le handler get
est utilisé pour intercepter les accès aux propriétés. Si la propriété existe dans l’objet cible, elle est renvoyée, sinon un message d’erreur est affiché.
Conclusion
Les décorateurs et le renvoi sont deux concepts importants en JavaScript qui permettent d’améliorer la modularité, la réutilisabilité et la lisibilité du code. Les décorateurs permettent d’ajouter du comportement à des fonctions ou des classes existantes de manière déclarative, tandis que le renvoi permet à un objet de déléguer les appels de méthodes ou les accès à des propriétés à un autre objet associé. Ensemble, ces techniques facilitent la création d’architectures logicielles flexibles et maintenables dans les applications JavaScript modernes.