"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Comprendre le code propre : les systèmes ⚡️

Comprendre le code propre : les systèmes ⚡️

Publié le 2024-11-02
Parcourir:103

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 dans 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 l'ensemble du système plus facile à comprendre et à modifier.

Exemple : Organisation d'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 souhaitons modifier 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 : Gérer le paiement séparément

Dans l'exemple du panier d'achat, le traitement des paiements 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 panier

// 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, les changements 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 en tant qu'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 ! ?

Déclaration de sortie Cet article est reproduit sur : https://dev.to/alisamir/understanding-clean-code-systems-53da?1 En cas de violation, veuillez contacter [email protected] pour le supprimer.
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3