首页  >  文章  >  web前端  >  Understanding Clean Code: Systems ⚡️

Understanding Clean Code: Systems ⚡️

DDD
DDD原创
2024-09-18 13:49:32851浏览

Understanding Clean Code: Systems ⚡️

When building software systems, it's crucial to manage codebase complexity.

Clean Code's Chapter 11 discusses designing modular systems that are easier to maintain and adapt over time.

We can use JavaScript examples to illustrate these concepts.


? The Problem with Large Systems

As systems grow, they naturally become more complex. This complexity can make it difficult to:

  • Understand the system as a whole.
  • Make changes without causing unintended side effects.
  • Scale the system with new features or requirements.

A well-designed system should be easy to modify, testable, and scalable. The secret to achieving this lies in modularity and careful separation of concerns.


? Modularity: Divide and Conquer

At the heart of clean systems design is the principle of modularity. You make the system more manageable by breaking a large system into smaller, independent modules, each with a clear responsibility.

Each module should encapsulate a specific functionality, making the overall system easier to understand and change.

Example: Organizing a Shopping Cart System

Let’s imagine a shopping cart system in JavaScript. Instead of lumping all logic into a single file, you can break the system into several 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()}`);

The responsibilities are divided here: Cart manages the items, Item represents a product, and order.js orchestrates the interactions.

This separation ensures that each module is self-contained and easier to test and change independently.


? Encapsulation: Hide Implementation Details

One of the goals of modularity is encapsulation—hiding the internal workings of a module from the rest of the system.

External code should only interact with a module through its well-defined interface.

This makes changing the module’s internal implementation easier without affecting other parts of the system.

Example: Encapsulating Cart Logic

Let’s say we want to change how we calculate the total in the Cart. Maybe now we need to account for sales tax. We can encapsulate this logic inside the Cart class:

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

Other parts of the system (like order.js) are unaffected by changes in how the total is calculated. This makes your system more flexible and easier to maintain.


? Separation of Concerns: Keep Responsibilities Clear

A common problem in large systems is that different parts of the system get entangled.

When a module starts taking on too many responsibilities, it becomes harder to change or reuse in different contexts.

The separation of concerns principle ensures that each module has one specific responsibility.

Example: Handling Payment Separately

In the shopping cart example, payment processing should be handled in a separate module:

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

Now, the payment logic is separated from cart management. This makes it easy to modify the payment process later (e.g., integrating with a different payment provider) without affecting the rest of the system.


? Testing Modules Independently

One of the greatest benefits of modularity is that you can test each module independently.

In the example above, you could write unit tests for the Cart class without needing to worry about how payments are processed.

Example: Unit Testing the Cart

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

With a clear separation of concerns, each module can be tested in isolation, making debugging easier and development faster.


? Handling Dependencies: Avoid Tight Coupling

When modules depend too heavily on each other, changes in one part of the system can have unexpected consequences elsewhere.

To minimize this, aim for loose coupling between modules.

This allows each module to evolve independently.

Example: Injecting Dependencies

Instead of hardcoding dependencies inside a module, pass them in as 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);
    }
}

This approach makes the Cart class more flexible and easier to test with different tax calculations.


Conclusion: Keep Systems Modular, Flexible, and Easy to Change

Happy Coding! ?

以上是Understanding Clean Code: Systems ⚡️的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn