JavaScript中的SOLID原则:从理论到实践的代码示例

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript中的SOLID原则:从A到Z的理论与实践



SOLID是罗伯特·马丁(Bob大叔)提出的面向对象编程五大基本原则的缩写。尽管JavaScript不是经典的面向对象语言(它使用原型继承),但这些原则同样适用于它,尤其是在Node.js和现代框架的背景下。遵循SOLID原则能使代码更灵活、更易测试和更易维护。在本文中,我们将通过JavaScript的实际示例来剖析每个原则。



1. S — 单一职责原则



一个类或模块应该只有一个修改的理由。换句话说,每个实体应该只负责一个特定的任务。



反面示例:User类同时管理用户数据和发送电子邮件通知。



class User {    constructor(name, email) {        this.name = name;        this.email = email;    }

saveToDatabase() { // 保存到数据库的逻辑 console.log(`将用户 ${this.name} 保存到数据库`); }

sendWelcomeEmail() { // 发送电子邮件的逻辑 console.log(`向 ${this.email} 发送欢迎邮件`); }}


正面示例:将职责分离到两个类中。



class User {    constructor(name, email) {        this.name = name;        this.email = email;    }}

class UserRepository { save(user) { console.log(`将用户 ${user.name} 保存到数据库`); }}

class EmailService { sendWelcome(user) { console.log(`向 ${user.email} 发送欢迎邮件`); }}

// 使用const user = new User('伊万', 'ivan@example.com');const repo = new UserRepository();const emailService = new EmailService();

repo.save(user);emailService.sendWelcome(user);


2. O — 开闭原则



软件实体应对扩展开放,对修改关闭。这意味着新功能应通过添加新代码来实现,而不是修改现有代码。



反面示例:添加新图形时需要修改AreaCalculator类。



class AreaCalculator {    calculate(shape) {        if (shape.type === 'circle') {            return Math.PI * shape.radius ** 2;        } else if (shape.type === 'rectangle') {            return shape.width * shape.height;        }        // 添加新图形时需要修改此方法    }}


正面示例:使用多态和继承。



class Shape {    area() {        throw new Error('area() 方法必须被重写');    }}

class Circle extends Shape { constructor(radius) { super(); this.radius = radius; }

area() { return Math.PI * this.radius ** 2; }}

class Rectangle extends Shape { constructor(width, height) { super(); this.width = width; this.height = height; }

area() { return this.width * this.height; }}

class AreaCalculator { calculate(shape) { return shape.area(); }}

// 使用const calculator = new AreaCalculator();const circle = new Circle(5);const rectangle = new Rectangle(4, 6);

console.log(calculator.calculate(circle)); // 78.54console.log(calculator.calculate(rectangle)); // 24


3. L — 里氏替换原则



程序中的对象应该可以被其子类的实例替换,而不会影响程序的正确性。简而言之,子类应扩展父类的功能,而不应改变父类的行为。

博客

书籍推荐