SOLID 原則是物件導向程式設計中的設計原則,可協助開發人員建立更易於理解、靈活且可維護的軟體。

讓我們深入研究每個原則,看看如何使用 JavaScript 應用它們。


📌 1.單一職責原則(SRP)

定義:一個類別應該只有一個改變的理由,這意味著它應該只有一項工作或責任。

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

class UserService {
  createUser(user) {
    // logic to create user
  }

  getUser(id) {
    // logic to get user
  }
}

class UserNotificationService {
  sendWelcomeEmail(user) {
    // logic to send email
  }
}

const user = new User('John Doe', '[email protected]');
const userService = new UserService();
userService.createUser(user);

const notificationService = new UserNotificationService();
notificationService.sendWelcomeEmail(user);

這裡, User處理使用者資料, UserService處理與使用者相關的操作, UserNotificationService處理通知。每個類別都有一個職責。


📌2.開閉原則(OCP)

定義:軟體實體應該對擴充開放,但對修改關閉。

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

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

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

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

const shapes = [new Rectangle(4, 5), new Circle(3)];

const totalArea = shapes.reduce((sum, shape) => sum + shape.area(), 0);
console.log(totalArea);

在此範例中,可以擴展每個形狀類別的area方法(如RectangleCircle ),而無需修改形狀類別的現有程式碼。這允許將來加入新形狀而無需更改現有形狀。


📌 3.里氏替換原理(LSP)

定義:子類型必須可以替換其基底類型,而不改變程式的正確性。

class Bird {
  fly() {
    console.log('I can fly');
  }
}

class Duck extends Bird {}

class Ostrich extends Bird {
  fly() {
    throw new Error('I cannot fly');
  }
}

function makeBirdFly(bird) {
  bird.fly();
}

const duck = new Duck();
makeBirdFly(duck); // Works fine

const ostrich = new Ostrich();
makeBirdFly(ostrich); // Throws error

在此範例中, Ostrich違反了 LSP,因為它改變了fly方法的預期行為。為了遵守LSP,我們應該確保子類別不會改變基底類別所期望的行為。


📌 4.介面隔離原則(ISP)

定義:不應強迫客戶端依賴他們不使用的介面。

class Printer {
  print() {
    console.log('Printing document');
  }
}

class Scanner {
  scan() {
    console.log('Scanning document');
  }
}

class MultiFunctionPrinter {
  print() {
    console.log('Printing document');
  }

  scan() {
    console.log('Scanning document');
  }
}

const printer = new Printer();
printer.print();

const scanner = new Scanner();
scanner.scan();

const multiFunctionPrinter = new MultiFunctionPrinter();
multiFunctionPrinter.print();
multiFunctionPrinter.scan();

在這裡, PrinterScanner類別提供特定的功能,而不強迫客戶端實作他們不需要的方法。 MultiFunctionPrinter可以使用這兩種功能,並遵守 ISP。


📌5.依賴倒置原則(DIP)

定義:高層模組不應該依賴低層模組。兩者都應該依賴抽象。抽像不應該依賴細節。細節應該取決於抽象。

class NotificationService {
  constructor(sender) {
    this.sender = sender;
  }

  sendNotification(message) {
    this.sender.send(message);
  }
}

class EmailSender {
  send(message) {
    console.log(`Sending email: ${message}`);
  }
}

class SMSSender {
  send(message) {
    console.log(`Sending SMS: ${message}`);
  }
}

const emailSender = new EmailSender();
const notificationService = new NotificationService(emailSender);
notificationService.sendNotification('Hello via Email');

const smsSender = new SMSSender();
const notificationServiceWithSMS = new NotificationService(smsSender);
notificationServiceWithSMS.sendNotification('Hello via SMS');

在此範例中, NotificationService依賴抽象( sender ),允許它與任何發送者實作(如EmailSenderSMSSender )一起使用。這透過使高階模組 ( NotificationService ) 依賴抽象而非具體實作來遵守 DIP。



結論✅

透過遵循 SOLID 原則,您可以設計出更健壯、可維護和可擴展的 JavaScript 應用程式。

這些原則有助於確保您的程式碼庫保持乾淨和靈活,從而隨著應用程式的成長更容易管理和擴展。

一致地應用這些原則可以顯著提高軟體的品質。


快樂編碼! 🔥

LinkedInX (Twitter)TelegramYouTubeDiscordFacebookInstagram


原文出處:https://dev.to/alisamirali/mastering-solid-principles-1aa6


共有 0 則留言