Maison  >  Article  >  interface Web  >  Comprendre le code propre : les systèmes ⚡️

Comprendre le code propre : les systèmes ⚡️

DDD
DDDoriginal
2024-09-18 13:49:32854parcourir

Understanding Clean Code: Systems ⚡️

Lors de la création de systèmes logiciels, il est crucial de gérer la complexité de la base de code.

Le chapitre 11 de Clean Code traite de la conception de systèmes modulaires plus faciles à entretenir et à adapter au fil du temps.

Nous pouvons utiliser des exemples JavaScript pour illustrer ces concepts.


? Le problème des grands systèmes

À mesure que les systèmes se développent, ils deviennent naturellement plus complexes. Cette complexité peut rendre difficile :

  • Comprendre le système dans son ensemble.
  • Apportez des modifications sans provoquer d'effets secondaires involontaires.
  • Faites évoluer le système avec de nouvelles fonctionnalités ou exigences.

Un système bien conçu doit être facile à modifier, testable et évolutif. Le secret pour y parvenir réside dans la modularité et une séparation minutieuse des préoccupations.


? Modularité : diviser pour régner

Au cœur de la conception de systèmes propres se trouve le principe de modularité. Vous rendez le système plus gérable en divisant un grand système en modules plus petits et indépendants, chacun ayant une responsabilité claire.

Chaque module doit encapsuler une fonctionnalité spécifique, rendant le système global plus facile à comprendre et à modifier.

Exemple : Organiser un système de panier d'achat

Imaginons un système de panier d'achat en JavaScript. Au lieu de regrouper toute la logique dans un seul fichier, vous pouvez diviser le système en plusieurs modules :

// cart.js
export class Cart {
    constructor() {
        this.items = [];
    }

    addItem(item) {
        this.items.push(item);
    }

    getTotal() {
        return this.items.reduce((total, item) => total + item.price, 0);
    }
}

// item.js
export class Item {
    constructor(name, price) {
        this.name = name;
        this.price = price;
    }
}

// order.js
import { Cart } from './cart.js';
import { Item } from './item.js';

const cart = new Cart();
cart.addItem(new Item('Laptop', 1000));
cart.addItem(new Item('Mouse', 25));

console.log(`Total: $${cart.getTotal()}`);

Les responsabilités sont réparties ici : Cart gère les articles, Item représente un produit et order.js orchestre les interactions.

Cette séparation garantit que chaque module est autonome et plus facile à tester et à modifier indépendamment.


? Encapsulation : masquer les détails de l'implémentation

L'un des objectifs de la modularité est l'encapsulation : cacher le fonctionnement interne d'un module au reste du système.

Le code externe ne doit interagir avec un module que via son interface bien définie.

Cela facilite la modification de l'implémentation interne du module sans affecter les autres parties du système.

Exemple : Encapsulation de la logique du panier

Disons que nous voulons changer la façon dont nous calculons le total dans le panier. Peut-être que nous devons maintenant tenir compte de la taxe de vente. Nous pouvons encapsuler cette logique dans la classe Cart :

// cart.js
export class Cart {
    constructor(taxRate) {
        this.items = [];
        this.taxRate = taxRate;
    }

    addItem(item) {
        this.items.push(item);
    }

    getTotal() {
        const total = this.items.reduce((sum, item) => sum + item.price, 0);
        return total + total * this.taxRate;
    }
}

// Now, the rest of the system does not need to know about tax calculations.

Les autres parties du système (comme order.js) ne sont pas affectées par les changements dans la façon dont le total est calculé. Cela rend votre système plus flexible et plus facile à entretenir.


? Séparation des préoccupations : garder les responsabilités claires

Un problème courant dans les grands systèmes est que différentes parties du système s'enchevêtrent.

Lorsqu'un module commence à assumer trop de responsabilités, il devient plus difficile de le modifier ou de le réutiliser dans différents contextes.

Le principe de séparation des préoccupations garantit que chaque module a une responsabilité spécifique.

Exemple : traiter le paiement séparément

Dans l'exemple du panier, le traitement du paiement doit être géré dans un module séparé :

// payment.js
export class Payment {
    static process(cart) {
        const total = cart.getTotal();
        console.log(`Processing payment of $${total}`);
        // Payment logic goes here
    }
}

// order.js
import { Cart } from './cart.js';
import { Payment } from './payment.js';

const cart = new Cart(0.07); // 7% tax rate
cart.addItem(new Item('Laptop', 1000));
cart.addItem(new Item('Mouse', 25));

Payment.process(cart);

Désormais, la logique de paiement est séparée de la gestion du panier. Cela facilite la modification ultérieure du processus de paiement (par exemple, l'intégration avec un autre fournisseur de paiement) sans affecter le reste du système.


? Tester les modules indépendamment

L'un des plus grands avantages de la modularité est que vous pouvez tester chaque module indépendamment.

Dans l'exemple ci-dessus, vous pouvez écrire des tests unitaires pour la classe Cart sans avoir à vous soucier de la façon dont les paiements sont traités.

Exemple : test unitaire du chariot

// cart.test.js
import { Cart } from './cart.js';
import { Item } from './item.js';

test('calculates total with tax', () => {
    const cart = new Cart(0.05); // 5% tax
    cart.addItem(new Item('Book', 20));

    expect(cart.getTotal()).toBe(21);
});

Avec une séparation claire des préoccupations, chaque module peut être testé isolément, ce qui facilite le débogage et accélère le développement.


? Gestion des dépendances : évitez les couplages étroits

Lorsque les modules dépendent trop les uns des autres, des modifications dans une partie du système peuvent avoir des conséquences inattendues ailleurs.

Pour minimiser cela, visez un couplage lâche entre les modules.

Cela permet à chaque module d'évoluer indépendamment.

Exemple : injection de dépendances

Au lieu de coder en dur les dépendances à l'intérieur d'un module, transmettez-les comme arguments :

// cart.js
export class Cart {
    constructor(taxRateCalculator) {
        this.items = [];
        this.taxRateCalculator = taxRateCalculator;
    }

    addItem(item) {
        this.items.push(item);
    }

    getTotal() {
        const total = this.items.reduce((sum, item) => sum + item.price, 0);
        return total + this.taxRateCalculator(total);
    }
}

Cette approche rend la classe Cart plus flexible et plus facile à tester avec différents calculs de taxes.


Conclusion : Gardez les systèmes modulaires, flexibles et faciles à modifier

Bon codage ! ?

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Comprendre les micro-frontendsArticle suivant:Comprendre les micro-frontends