SOLID 原則是物件導向程式設計中的設計原則,可協助開發人員建立更易於理解、靈活且可維護的軟體。
讓我們深入研究每個原則,看看如何使用 JavaScript 應用它們。
定義:一個類別應該只有一個改變的理由,這意味著它應該只有一項工作或責任。
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
處理通知。每個類別都有一個職責。
定義:軟體實體應該對擴充開放,但對修改關閉。
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
方法(如Rectangle
和Circle
),而無需修改形狀類別的現有程式碼。這允許將來加入新形狀而無需更改現有形狀。
定義:子類型必須可以替換其基底類型,而不改變程式的正確性。
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,我們應該確保子類別不會改變基底類別所期望的行為。
定義:不應強迫客戶端依賴他們不使用的介面。
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();
在這裡, Printer
和Scanner
類別提供特定的功能,而不強迫客戶端實作他們不需要的方法。 MultiFunctionPrinter
可以使用這兩種功能,並遵守 ISP。
定義:高層模組不應該依賴低層模組。兩者都應該依賴抽象。抽像不應該依賴細節。細節應該取決於抽象。
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
),允許它與任何發送者實作(如EmailSender
或SMSSender
)一起使用。這透過使高階模組 ( NotificationService
) 依賴抽象而非具體實作來遵守 DIP。
透過遵循 SOLID 原則,您可以設計出更健壯、可維護和可擴展的 JavaScript 應用程式。
這些原則有助於確保您的程式碼庫保持乾淨和靈活,從而隨著應用程式的成長更容易管理和擴展。
一致地應用這些原則可以顯著提高軟體的品質。
快樂編碼! 🔥
LinkedIn 、 X (Twitter) 、 Telegram 、 YouTube 、 Discord 、 Facebook 、 Instagram
原文出處:https://dev.to/alisamirali/mastering-solid-principles-1aa6