Principes SOLID en JavaScript : théorie et pratique

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction aux principes SOLID en JavaScript

SOLID est l'acronyme de cinq principes fondamentaux de la programmation orientée objet, formulés par Robert Martin (Uncle Bob). Bien que JavaScript n'ait pas été initialement un langage OOP strictement typé, le JavaScript moderne (ES6+) avec ses classes, modules et TypeScript utilise activement ces principes pour créer des applications évolutives et maintenables, notamment dans l'environnement Node.js.

Dans cet article, nous allons analyser chacun des cinq principes SOLID avec des exemples pratiques de code en JavaScript. La compréhension de ces principes vous aidera à écrire un code propre, flexible et résistant aux changements.



1. Single Responsibility Principle (SRP) — Principe de responsabilité unique

Le principe stipule : une classe ou un module ne doit avoir qu'une seule raison de changer. Autrement dit, chaque module est responsable d'une fonctionnalité spécifique.

Violation du SRP

Considérons la classe UserService, qui gère simultanément les utilisateurs, envoie des emails et journalise les actions :

class UserService {  constructor() {    this.users = [];  }

addUser(name) { this.users.push({ name }); console.log('User added'); // Journalisation this.sendEmail(name); // Envoi d'email }

sendEmail(name) { console.log(`Email sent to ${name}`); }

getUsers() { return this.users; }}

Ici, la classe a trois responsabilités : la gestion des données, la journalisation et l'envoi de notifications. Un changement dans la logique de journalisation ou d'envoi d'email entraînera une modification de la classe UserService.

Respect du SRP

Séparons les responsabilités en classes distinctes :

class Logger {  log(message) {    console.log(`[LOG]: ${message}`);  }}

class EmailService { send(name) { console.log(`Email sent to ${name}`); }}

class UserService { constructor(logger, emailService) { this.users = []; this.logger = logger; this.emailService = emailService; }

addUser(name) { this.users.push({ name }); this.logger.log(`User ${name} added`); this.emailService.send(name); }

getUsers() { return this.users; }}

Désormais, chaque classe est responsable de sa propre tâche, et les modifications dans un service n'affectent pas les autres.



2. Open-Closed Principle (OCP) — Principe d'ouverture/fermeture

Le principe stipule : les entités logicielles doivent être ouvertes à l'extension, mais fermées à la modification. C'est-à-dire que nous devons pouvoir ajouter de nouvelles fonctionnalités sans modifier le code existant.

Violation de l'OCP

Supposons que nous ayons une fonction pour calculer l'aire de figures :

function calculateArea(shape) {  if (shape.type === 'circle') {    return Math.PI * shape.radius ** 2;  } else if (shape.type === 'rectangle') {    return shape.width * shape.height;  }  // L'ajout d'une nouvelle figure nécessitera de modifier cette fonction}

Respect de l'OCP

Utilisons le polymorphisme via des classes :

class Shape {  area() {    throw new Error('Method "area()" must be implemented');  }}

class Circle extends Shape { constructor(radius) { super(); this.radius = radius; } area() { return Math.PI * this.radius ** 2; }}

class Rectangle extends Shape { constructor(width, height) { super(); this.width = width; this.height = height; } area() { return this.width * this.height; }}

// Ajout d'une nouvelle figure sans modifier le code existantclass Triangle extends Shape { constructor(base, height) { super(); this.base = base; this.height = height; } area() { return (this.base * this.height) / 2; }}

function calculateArea

Blogs

Book Recommendations