Architekt systemówArchitekt, Programista Backend

Co oznacza zasada "Inwersja Zależności" w projektowaniu architektury i czym różni się od zwykłej inwersji zależności w kodzie?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Zasada Inwersji Zależności (DIP) — to zasada architektoniczna, wg której:

  • Moduły wysokiego poziomu nie powinny zależeć od modułów niskiego poziomu. Oba rodzaje powinny polegać na abstrahencjach (interfejsach).
  • Abstrahencje nie powinny zależeć od szczegółów, szczegóły powinny zależeć od abstrahencji.

Oznacza to, że logika biznesowa (np. serwis do obsługi zamówień) nie powinna znać i bezpośrednio używać konkretnej implementacji infrastruktury (np. klasy realizującej wysyłkę maili), lecz pracować przez abstrahencję (interfejs), który jest wstrzykiwany przez mechanizm kontenera DI lub ręcznie.

Przykład kodu w C#:

public interface IEmailSender { void Send(string to, string message); } public class SmtpEmailSender : IEmailSender { public void Send(string to, string message) { // Implementacja wysyłki emaila } } public class OrderService { private readonly IEmailSender _emailSender; public OrderService(IEmailSender emailSender) { _emailSender = emailSender; } public void PlaceOrder(string customer) { // logika biznesowa _emailSender.Send(customer, "Twoje zamówienie zostało złożone!"); } }

Kluczowe cechy:

  • Umożliwia łatwą wymianę szczegółów implementacji (np. wprowadzenie mocka w testach).
  • Zwiększa testowalność i rozszerzalność architektury.
  • Zapewnia słabą powiązanie modułów.

Pytania z pułapką.

Czy DIP to tylko wstrzykiwanie zależności przez konstruktor?

Nie. DIP dotyczy oddzielenia abstrahencji od implementacji. Wstrzykiwanie zależności (Dependency Injection, DI) to tylko narzędzie, za pomocą którego realizuje się DIP. DIP można wdrożyć także bez kontenera DI, ręcznie zapewniając separację abstrahencji i szczegółów.

Czy w przypadku jednej implementacji interfejsu DIP jest obowiązkowe?

Tak, zasada nadal ma zastosowanie, jeśli istnieje możliwość rozszerzenia. Wprowadzenie abstrahencji przygotowuje system na zmiany wymagań bez modyfikacji kodu wysokiego poziomu. Nawet przy jednej implementacji interfejsu, słabe powiązanie ułatwia testowanie i rozwój systemu.

Czy można naruszyć DIP, używając logiki w fabrykach lub lokalizatorach serwisów?

Tak. Jeśli fabryka lub lokalizator serwisów zna szczegóły implementacji i dynamicznie wiąże je bez użycia interfejsu po stronie klienta, DIP jest naruszane, mimo zewnętrznej obecności abstrahencji.