Principes SOLID en TypeScript : théorie et pratique avec exemples

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 : Pourquoi SOLID est important en TypeScript



Lors du développement en TypeScript, en particulier dans les grands projets, maintenir la propreté et la flexibilité du code devient crucial. SOLID est un ensemble de cinq principes fondamentaux de la programmation orientée objet qui aident à créer des applications évolutives, facilement testables et maintenables. Ces principes sont particulièrement pertinents pour TypeScript, qui ajoute le typage statique et les interfaces à JavaScript, offrant des outils puissants pour leur mise en œuvre.



Dans cet article, nous allons détailler chacun des cinq principes SOLID du point de vue de TypeScript, en accompagnant la théorie d'exemples de code pratiques. Vous apprendrez comment appliquer ces principes pour améliorer l'architecture de vos projets.



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



Théorie : Chaque classe ou module ne doit avoir qu'une seule raison de changer. En d'autres termes, une classe ne doit être responsable que d'une seule partie de la fonctionnalité du programme.



Violation du principe :



// ❌ Mauvais : la classe est responsable des données, de la sauvegarde et du formatageclass User {  constructor(public name: string, public email: string) {}

saveToDatabase(): void { console.log(`Sauvegarde de ${this.name} dans la BDD`); }

generateHTML(): string { return `<div>${this.name} - ${this.email}</div>`; }}


Correction avec l'application du SRP :



// ✅ Bien : on sépare les responsabilités en trois classesclass User {  constructor(public name: string, public email: string) {}}

class UserRepository { save(user: User): void { console.log(`Sauvegarde de ${user.name} dans la BDD`); }}

class UserView { render(user: User): string { return `<div>${user.name} - ${user.email}</div>`; }}


Maintenant, chaque classe a une responsabilité claire et unique, ce qui simplifie les tests et la modification du code.



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



Théorie : Les entités logicielles (classes, modules, fonctions) doivent être ouvertes à l'extension, mais fermées à la modification. Cela signifie que vous devez pouvoir ajouter de nouvelles fonctionnalités sans modifier le code existant.



Violation du principe :



// ❌ Mauvais : lors de l'ajout d'un nouveau type de forme, il faut modifier la classe AreaCalculatorclass AreaCalculator {  calculate(shape: any): number {    if (shape.type === 'circle') {      return Math.PI * shape.radius ** 2;    } else if (shape.type === 'rectangle') {      return shape.width * shape.height;    }    return 0;  }}


Correction avec l'application de l'OCP :



// ✅ Bien : utilisation d'une interface et du polymorphismeinterface Shape {  area(): number;}

class Circle implements Shape { constructor(public radius: number) {} area(): number { return Math.PI * this.radius ** 2; }}

class Rectangle implements Shape { constructor(public width: number, public height: number) {} area(): number { return this.width * this.height; }}

class AreaCalculator { calculate(shape: Shape): number { return shape.area(); // Fermé à la modification, ouvert à l'extension }}


Maintenant, pour ajouter une nouvelle forme (par exemple, Triangle), il suffit de créer une nouvelle classe implémentant l'interface Shape — sans modifier AreaCalculator.



3. Liskov Substitution Principle (Principe de substitution de Barbara Liskov)



Théorie : Les objets d'un programme doivent être remplaçables par des instances de leurs sous-types sans altérer la correction du programme. Si vous avez une classe de base et un héritier, le code qui fonctionne avec la classe de base doit également fonctionner correctement avec l'héritier.



Violation du principe :



// ❌ Mauv                

Blogs

Book Recommendations