探索 NestJS 的依賴注入系統引發了對依賴反轉、控制反轉和依賴注入的更深入研究。 這些概念雖然看似相似,但卻為不同的問題提供了不同的解決方案。 此解釋可作為個人複習,並希望能為其他處理這些術語的人提供有用的指南。
定義:高層模組不應該依賴低層模組;兩者都應該依賴抽象。抽像不應該依賴細節;細節應該取決於抽象。
在軟體中,高層模組封裝核心業務邏輯,而低層模組處理特定的實作(資料庫、API 等)。 如果沒有 DIP,高層模組直接依賴低層模組,造成緊密耦合,阻礙靈活性,使測試和維護複雜化,並且使替換或擴展低層細節變得困難。
DIP 顛倒了這種關係。高層和低層模組都依賴共享抽象(介面或抽象類別),而不是直接控制。
<code class="language-python">class EmailService: def send_email(self, message): print(f"Sending email: {message}") class Notification: def __init__(self): self.email_service = EmailService() def notify(self, message): self.email_service.send_email(message)</code>
<code class="language-typescript">class EmailService { sendEmail(message: string): void { console.log(`Sending email: ${message}`); } } class Notification { private emailService: EmailService; constructor() { this.emailService = new EmailService(); } notify(message: string): void { this.emailService.sendEmail(message); } }</code>
問題:
Notification
直接依賴EmailService
。 SMSService
需要修改Notification
。 <code class="language-python">from abc import ABC, abstractmethod class MessageService(ABC): @abstractmethod def send_message(self, message): pass class EmailService(MessageService): def send_message(self, message): print(f"Sending email: {message}") class Notification: def __init__(self, message_service: MessageService): self.message_service = message_service def notify(self, message): self.message_service.send_message(message) # Usage email_service = EmailService() notification = Notification(email_service) notification.notify("Hello, Dependency Inversion!")</code>
<code class="language-typescript">interface MessageService { sendMessage(message: string): void; } class EmailService implements MessageService { sendMessage(message: string): void { console.log(`Sending email: ${message}`); } } class Notification { private messageService: MessageService; constructor(messageService: MessageService) { this.messageService = messageService; } notify(message: string): void { this.messageService.sendMessage(message); } } // Usage const emailService = new EmailService(); const notification = new Notification(emailService); notification.notify("Hello, Dependency Inversion!");</code>
IoC 是一種設計原則,其中依賴控制轉移到外部系統(框架)而不是在類別內進行管理。 傳統上,類別會建立並管理其相依性。 IoC 逆轉了這一點——外部實體注入依賴項。
<code class="language-python">class SMSService: def send_message(self, message): print(f"Sending SMS: {message}") class Notification: def __init__(self): self.sms_service = SMSService() # Dependency created internally def notify(self, message): self.sms_service.send_message(message)</code>
<code class="language-typescript">class SMSService { sendMessage(message: string): void { console.log(`Sending SMS: ${message}`); } } class Notification { private smsService: SMSService; constructor() { this.smsService = new SMSService(); // Dependency created internally } notify(message: string): void { this.smsService.sendMessage(message); } }</code>
沒有 IoC 的問題:
<code class="language-python">class EmailService: def send_email(self, message): print(f"Sending email: {message}") class Notification: def __init__(self): self.email_service = EmailService() def notify(self, message): self.email_service.send_email(message)</code>
<code class="language-typescript">class EmailService { sendEmail(message: string): void { console.log(`Sending email: ${message}`); } } class Notification { private emailService: EmailService; constructor() { this.emailService = new EmailService(); } notify(message: string): void { this.emailService.sendEmail(message); } }</code>
DI 是一種物件從外部來源接收其相依性的技術。 這是 IoC 的實際實現,透過以下方式註入依賴項:
injector
函式庫)<code class="language-python">from abc import ABC, abstractmethod class MessageService(ABC): @abstractmethod def send_message(self, message): pass class EmailService(MessageService): def send_message(self, message): print(f"Sending email: {message}") class Notification: def __init__(self, message_service: MessageService): self.message_service = message_service def notify(self, message): self.message_service.send_message(message) # Usage email_service = EmailService() notification = Notification(email_service) notification.notify("Hello, Dependency Inversion!")</code>
tsyringe
函式庫)<code class="language-typescript">interface MessageService { sendMessage(message: string): void; } class EmailService implements MessageService { sendMessage(message: string): void { console.log(`Sending email: ${message}`); } } class Notification { private messageService: MessageService; constructor(messageService: MessageService) { this.messageService = messageService; } notify(message: string): void { this.messageService.sendMessage(message); } } // Usage const emailService = new EmailService(); const notification = new Notification(emailService); notification.notify("Hello, Dependency Inversion!");</code>
這個詳細的解釋闡明了 DIP、IoC 和 DI 之間的關係和區別,強調了它們對構建健壯且可維護的軟體的個人貢獻。
以上是分解依賴倒置、IoC 和 DI的詳細內容。更多資訊請關注PHP中文網其他相關文章!