Salut !
J'ai récemment parcouru plusieurs ressources de connaissances pour en savoir plus sur les modèles de conception et d'architecture populaires dans Node.js. Mon objectif était principalement du côté du serveur (backend), mais au fur et à mesure que je les parcourais, je voyais beaucoup de similitudes avec les frameworks du navigateur (frontend). Certains d'entre eux sont même directement utilisés dans les frameworks dont je suis d'autant plus content car je les utilisais déjà sans le savoir ?
Il existe de nombreux (très nombreux) modèles de conception que vous pouvez utiliser, c'est pourquoi dans cet article, j'ai décidé d'en choisir 10 et de les expliquer plus en détail.
Profitez !
Les modèles de conception sont des solutions éprouvées et testées pour résoudre les problèmes que nous, en tant que développeurs, rencontrons quotidiennement. Ces modèles aident à promouvoir les meilleures pratiques et à mettre en œuvre une approche structurée pour résoudre les problèmes quotidiens lors de la conception et du développement d'une architecture logicielle. Les ingénieurs logiciels peuvent développer des systèmes maintenables, sécurisés et stables en utilisant ces modèles.
Node.js, en raison de sa flexibilité, ne vous oblige pas à vous en tenir à certains modèles mais vous donne plutôt la liberté de choisir uniquement ceux nécessaires à votre tâche. C'est pourquoi à mon avis il est si largement utilisé aujourd'hui (et d'ailleurs grâce à JavaScript :D).
Ci-dessous, vous verrez une liste de 5 modèles de conception sélectionnés que j'aime.
Ce modèle concerne les classes qui ne peuvent avoir qu'une seule instance et y fournir un accès global. Les modules peuvent être mis en cache et partagés dans l'application dans Node.js, ce qui contribuera à améliorer l'efficacité des ressources. Un exemple courant d'un tel modèle singleton est un module de connexion à certains services tiers tels que des bases de données, des services de cache, des fournisseurs de messagerie, etc., largement utilisé dans le framework Nest.js. Jetons un coup d'œil à l'exemple suivant :
class Redis { constructor() { this.connection = null; } static getInstance() { if (!Redis. instance) { Redis.instance = new Redis(options); } Return Redis.instance; } connect() { this.connection = 'Redis connected' } }
Et puis nous pouvons l'utiliser comme suit :
const medicine = Redis.getInstance(); const redisTwo = Redis.getInstance(); console.log(redisOne === RedisTwo); // it will result to `true` redisOne.connect(); console.log(redisOne.connection) // 'Redis connected' console.log(redisTwo.connection) // 'Redis connected'
Cette approche garantit qu'il n'y a qu'une seule connexion à Redis et évite la duplication des connexions.
Avec ce modèle, vous pouvez créer de nouveaux objets sans spécifier la classe d'objet qui sera créée. Grâce à lui, nous faisons abstraction de la création d'objets qui peuvent contribuer à améliorer la lisibilité et la réutilisabilité du code :
class Character { constructor(name, health) { this.name = name; this.health = health; } } class CharacterFactory { createCharacter(name) { switch(name) { case 'mage': return new Character('Powerful Mage', 8); case 'warrior': return new Character('Courageous Warrior', 10); case 'rogue': return new Character('Sneaky Rogue', 9) default: return new Error('Unknown character'); } } }
Et puis nous pouvons l'utiliser comme suit :
const characterFactory = new CharacterFactory(); const mage = characterFactory.createCharacter('mage'); const warrior = characterFactory.createCharacter('warrior'); console.log(mage.name) // Powerful Mage console.log(warrior.name) // Courageous Warrior
Cette approche permet aux consommateurs de cette usine d'utiliser le code de l'usine au lieu d'utiliser directement le constructeur de classe Character.
Ce modèle fonctionne de manière à ce que vous ayez une entité qui gère la liste des éléments dépendants appelés observateurs et les informe si l'état change. Ce modèle est largement utilisé dans le framework Vue.js et peut être implémenté comme ceci :
class Topic { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(o => o !== observer); } notify(data) { this.observers.forEach(o => o.update(data)); } } class Observer { constructor(name) { this.name = name; } update(data) { console.log(`${this.name} received ${data}`); } }
Et vous pouvez l'utiliser comme suit :
const topic = new Topic(); const observer1 = new Observer('Observer 1'); const observer2 = new Observer('Observer 2'); topic.subscribe(observer1); topic.subscribe(observer2); topic.notify('Hello World'); // Observer 1 received Hello World // Observer 2 received Hello World topic.unsubscribe(observer2); topic.notify('Hello Again'); // Observer 1 received Hello Again
C'est un modèle très utile pour la gestion des événements et les workflows asynchrones qui permet de mettre à jour plusieurs objets sans coupler l'éditeur aux abonnés.
Ce modèle est très utile pour étendre la fonctionnalité existante avec une nouvelle sans affecter les instances initiales/originales. Il est largement utilisé dans le framework Nest.js grâce à la prise en charge complète de TypeScript, mais dans Node.js standard, il peut être utilisé dans les cas suivants :
class Character { constructor() { this.endurance = 10; } getEndurance() { return this.endurance; } } class CharacterActions { constructor(character) { this.character = character; } attack() { this.character.endurance -= 2; } rest() { this.character.endurance += 1; } }
Et puis il peut être utilisé comme suit :
const character = new Character(); console.log(character.getEndurance()); // 10 const characterWithActions = new CharacterActions(character); characterWithActions.attack(); // - 2 characterWithActions.rest(); // + 1 console.log(characterWithActions.character.getEndurance()); // 9
En utilisant ce modèle, nous pouvons facilement étendre des classes déjà existantes sans affecter leurs fonctionnalités de base.
Dans ce modèle, les classes ou modules reçoivent des dépendances provenant de sources externes plutôt que de les enregistrer en interne. Cette approche permet d'extraire certains éléments réutilisables de votre système pour faciliter les tests et la maintenance. Il est largement utilisé dans le framework Nest.js. Il peut être mis en œuvre comme suit :
class UserService { constructor(databaseService, loggerService) { this.db = databaseService; this.logger = loggerService; } async getUser(userId) { const user = await this.db.findUserById(userId); this.logger.log(`Fetched user ${user.name}`); return user; } }
Et puis, vous pouvez l'utiliser comme suit :
const databaseService = new Database(); const loggerService = new Logger(); const userService = new UserService(databaseService, loggerService); userService.getUser(1);
Cette approche vous permet d'extraire des éléments de votre système dans des entités indépendantes qui peuvent être injectées en cas de besoin.
Si vous souhaitez en savoir plus sur Vue, Nuxt, JavaScript ou d'autres technologies utiles, consultez VueSchool en cliquant sur ce lien ou en cliquant sur l'image ci-dessous :
Il couvre les concepts les plus importants lors de la création d'applications Vue ou Nuxt modernes qui peuvent vous aider dans votre travail quotidien ou vos projets parallèles ?
Bravo ! Vous venez d'apprendre comment fonctionnent certains modèles de conception dans Node.js et comment les implémenter.
Prends soin de toi et à la prochaine fois !
Et bon codage comme toujours ?️
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!