Maison >développement back-end >Tutoriel Python >Décomposer l'inversion de dépendance, l'IoC et la DI
L'exploration du système d'injection de dépendances de NestJS a déclenché une plongée plus approfondie dans l'inversion de dépendance, l'inversion de contrôle et l'injection de dépendance. Ces concepts, bien qu’apparemment similaires, offrent des solutions distinctes à différents problèmes. Cette explication sert de rappel personnel et, espérons-le, de guide utile pour ceux qui sont aux prises avec ces termes.
Définition : Les modules de haut niveau ne doivent pas dépendre des modules de bas niveau ; les deux devraient dépendre d’abstractions. Les abstractions ne devraient pas dépendre de détails ; les détails devraient dépendre des abstractions.
Dans les logiciels, les modules de haut niveau encapsulent la logique métier de base, tandis que les modules de bas niveau gèrent des implémentations spécifiques (bases de données, API, etc.). Sans DIP, les modules de haut niveau s'appuient directement sur ceux de bas niveau, créant un couplage étroit qui entrave la flexibilité, complique les tests et la maintenance et rend difficile le remplacement ou l'extension des détails de bas niveau.
DIP inverse cette relation. Au lieu d'un contrôle direct, les modules de haut niveau et de bas niveau dépendent d'une abstraction partagée (interface ou classe abstraite).
<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>
Problèmes :
Notification
dépend directement de EmailService
.SMSService
nécessite de modifier 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 est un principe de conception selon lequel le contrôle des dépendances est transféré vers un système externe (framework) au lieu d'être géré au sein de la classe. Traditionnellement, une classe crée et gère ses dépendances. IoC inverse cela : une entité externe injecte des dépendances.
<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>
Problèmes sans 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 est une technique où un objet reçoit ses dépendances d'une source externe. C'est une implémentation pratique d'IoC, injectant des dépendances via :
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>
Cette explication détaillée clarifie les relations et les distinctions entre DIP, IoC et DI, en mettant l'accent sur leurs contributions individuelles à la création de logiciels robustes et maintenables.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!