Principes Angular et SOLID

Mar 25 2023
SOLID est l'acronyme d'un ensemble de principes qui aident les développeurs à concevoir de meilleures applications logicielles. Ces principes sont les suivants : Dans Angular, vous pouvez créer des services qui ont une responsabilité unique, comme la récupération de données à partir d'une API ou la gestion de l'authentification des utilisateurs.

SOLID est l'acronyme d'un ensemble de principes qui aident les développeurs à concevoir de meilleures applications logicielles. Ces principes sont :

  1. Principe de responsabilité unique (SRP)
    '' Une classe ou un module ne doit avoir qu'une seule raison de changer. ''
    Cela signifie qu'une classe ne doit être responsable que d'une seule chose et ne doit pas avoir plusieurs responsabilités.
  2. Principe ouvert/fermé (OCP)
    '' Une classe doit être ouverte pour extension mais fermée pour modification.”
    Cela signifie que vous devriez pouvoir ajouter de nouvelles fonctionnalités à une classe sans modifier son code existant.
  3. Principe de substitution de Liskov (LSP)
    '' Les sous-types doivent être substituables à leurs types de base.
    Cela signifie que si une classe est dérivée d'une autre classe, elle devrait pouvoir remplacer la classe parente sans provoquer de comportement inattendu.
  4. Interface Segregation Principle (ISP)
    '' Les clients ne doivent pas être contraints de dépendre d'interfaces qu'ils n'utilisent pas.
    Cela signifie qu'une classe ne doit pas être forcée d'implémenter des interfaces dont elle n'a pas besoin.
  5. Principe d'inversion de dépendance (DIP)
    '' Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau. Les deux devraient dépendre d'abstractions. ''
    Cela signifie que les classes doivent dépendre d'abstractions plutôt que d'implémentations concrètes.

Dans Angular, vous pouvez créer des services qui ont une seule responsabilité, comme la récupération de données à partir d'une API ou la gestion de l'authentification des utilisateurs. Voici un exemple de service qui récupère les données d'une API :

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class DataService {
  constructor(private http: HttpClient) {}

  getData() {
    return this.http.get('https://jhonburbakollam.com/data');
  }
}

Principe ouvert/fermé (OCP)

Dans Angular, vous pouvez utiliser l'héritage et la composition pour créer des composants réutilisables qui peuvent être étendus ou modifiés sans changer leur code d'origine. Voici un exemple de composant qui utilise la composition :

import { Component } from '@angular/core';

@Component({
  selector: 'app-button',
  template: '<button>Click me!</button>'
})
export class ButtonComponent {}

import { Component } from '@angular/core';
import { ButtonComponent } from './button.component';

@Component({
  selector: 'app-custom-button',
  template: '<button>Custom text</button>'
})
export class CustomButtonComponent extends ButtonComponent {}

Principe de substitution de Liskov (LSP)

Dans Angular, vous pouvez utiliser des interfaces pour définir des contrats que les classes doivent suivre. Voici un exemple d'interface qui définit un contrat :

export interface DataService {
  getData(): Observable<any>;
}

Si vous avez une classe qui implémente cette interface, vous pouvez la remplacer par une autre classe qui implémente également l'interface sans provoquer de comportement inattendu.

Principe de ségrégation d'interface (ISP)

Dans Angular, vous pouvez utiliser des interfaces pour définir des contrats que les classes doivent suivre. Voici un exemple d'interface qui suit ISP :

export interface Logger {
  log(message: string): void;
}

En utilisant des interfaces, vous pouvez vous assurer que les classes ne dépendent que des interfaces dont elles ont besoin, plutôt que d'être obligées d'implémenter des interfaces qu'elles n'utilisent pas.

Principe d'inversion de dépendance (DIP)

Dans Angular, vous pouvez utiliser l'injection de dépendances pour fournir des instances de classes à d'autres classes. Voici un exemple de service qui utilise l'injection de dépendance :

import { Injectable } from '@angular/core';
import { DataService } from './data.service';

@Injectable()
export class LoggerService {
  constructor(private dataService: DataService) {}

  logData() {
    this.dataService.getData().subscribe((data) => {
      console.log(data);
    });
  }
}

En utilisant l'injection de dépendances, vous pouvez obtenir un couplage lâche entre les classes, ce qui vous permet d'échanger des implémentations sans modifier le code de la classe dépendante.