„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Clean Code verstehen: Systeme ⚡️

Clean Code verstehen: Systeme ⚡️

Veröffentlicht am 02.11.2024
Durchsuche:363

Understanding Clean Code: Systems ⚡️

Beim Erstellen von Softwaresystemen ist es entscheidend, die Komplexität der Codebasis zu verwalten.

In Kapitel 11 von Clean Code wird der Entwurf modularer Systeme erörtert, die einfacher zu warten und im Laufe der Zeit anzupassen sind.

Wir können JavaScript-Beispiele verwenden, um diese Konzepte zu veranschaulichen.


? Das Problem großer Systeme

Wenn Systeme wachsen, werden sie natürlich auch komplexer. Diese Komplexität kann Folgendes erschweren:

  • Das System als Ganzes verstehen.
  • Änderungen vornehmen, ohne unbeabsichtigte Nebenwirkungen zu verursachen.
  • Skalieren Sie das System mit neuen Funktionen oder Anforderungen.

Ein gut konzipiertes System sollte leicht zu modifizieren, testbar und skalierbar sein. Das Geheimnis, dies zu erreichen, liegt in der Modularität und der sorgfältigen Trennung der Belange.


? Modularität: Teile und herrsche

Im Mittelpunkt des sauberen Systemdesigns steht das Prinzip der Modularität. Sie machen das System besser verwaltbar, indem Sie ein großes System in kleinere, unabhängige Module mit jeweils klarer Verantwortung aufteilen.

Jedes Modul sollte eine bestimmte Funktionalität kapseln, damit das Gesamtsystem leichter zu verstehen und zu ändern ist.

Beispiel: Organisation eines Warenkorbsystems

Stellen wir uns ein Warenkorbsystem in JavaScript vor. Anstatt die gesamte Logik in einer einzigen Datei zusammenzufassen, können Sie das System in mehrere Module aufteilen:

// 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()}`);

Die Verantwortlichkeiten sind hier aufgeteilt: Cart verwaltet die Artikel, Item stellt ein Produkt dar und order.js orchestriert die Interaktionen.

Diese Trennung stellt sicher, dass jedes Modul in sich geschlossen ist und einfacher unabhängig getestet und geändert werden kann.


? Kapselung: Implementierungsdetails ausblenden

Eines der Ziele der Modularität ist die Kapselung – das Verbergen der internen Abläufe eines Moduls vor dem Rest des Systems.

Externer Code sollte nur über seine wohldefinierte Schnittstelle mit einem Modul interagieren.

Dies erleichtert die Änderung der internen Implementierung des Moduls, ohne dass sich dies auf andere Teile des Systems auswirkt.

Beispiel: Kapselung der Warenkorblogik

Angenommen, wir möchten ändern, wie wir die Gesamtsumme im Warenkorb berechnen. Vielleicht müssen wir jetzt die Umsatzsteuer berücksichtigen. Wir können diese Logik in der Cart-Klasse einkapseln:

// 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.

Andere Teile des Systems (wie order.js) sind von Änderungen in der Berechnung der Gesamtsumme nicht betroffen. Dadurch wird Ihr System flexibler und einfacher zu warten.


? Trennung von Belangen: Halten Sie die Verantwortlichkeiten klar

Ein häufiges Problem in großen Systemen besteht darin, dass verschiedene Teile des Systems miteinander verwickelt sind.

Wenn ein Modul zu viele Verantwortlichkeiten übernimmt, wird es schwieriger, es in verschiedenen Kontexten zu ändern oder wiederzuverwenden.

Das Prinzip der Trennung von Belangen stellt sicher, dass jedes Modul eine spezifische Verantwortung hat.

Beispiel: Separate Abwicklung von Zahlungen

Im Warenkorb-Beispiel sollte die Zahlungsabwicklung in einem separaten Modul abgewickelt werden:

// 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);

Jetzt ist die Zahlungslogik von der Warenkorbverwaltung getrennt. Dies macht es einfach, den Zahlungsprozess später zu ändern (z. B. die Integration mit einem anderen Zahlungsanbieter), ohne dass sich dies auf den Rest des Systems auswirkt.


? Module unabhängig testen

Einer der größten Vorteile der Modularität besteht darin, dass Sie jedes Modul unabhängig testen können.

Im obigen Beispiel könnten Sie Unit-Tests für die Cart-Klasse schreiben, ohne sich Gedanken darüber machen zu müssen, wie Zahlungen verarbeitet werden.

Beispiel: Unit-Test des Warenkorbs

// 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);
});

Mit einer klaren Trennung der Belange kann jedes Modul isoliert getestet werden, was das Debuggen erleichtert und die Entwicklung beschleunigt.


? Umgang mit Abhängigkeiten: Vermeiden Sie eine enge Kopplung

Wenn Module zu stark voneinander abhängig sind, können Änderungen in einem Teil des Systems unerwartete Folgen an anderer Stelle haben.

Um dies zu minimieren, achten Sie auf eine lockere Kopplung zwischen den Modulen.

Dadurch kann sich jedes Modul unabhängig weiterentwickeln.

Beispiel: Abhängigkeiten einfügen

Anstatt Abhängigkeiten innerhalb eines Moduls fest zu codieren, übergeben Sie sie als Argumente:

// 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);
    }
}

Dieser Ansatz macht die Cart-Klasse flexibler und einfacher mit verschiedenen Steuerberechnungen zu testen.


Fazit: Halten Sie Systeme modular, flexibel und leicht zu ändern

Viel Spaß beim Codieren! ?

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/alisamir/understanding-clean-code-systems-53da?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3