Приклад дотримання DIP
Коректне дотримання DIP досягається тоді, коли модуль високого рівня залежить не від конкретного класу, а від абстракції, а конкретна реалізація підставляється ззовні.
Нижче: правильний приклад.
Абстракція (контракт)
python
class OrderRepository:
def save(self, order):
raise NotImplementedErrorРеалізації нижнього рівня
python
class MySqlOrderRepository(OrderRepository):
def save(self, order):
print("Збереження в MySQL")
class PostgresOrderRepository(OrderRepository):
def save(self, order):
print("Збереження в Postgres")Модуль високого рівня (не залежить від деталей)
python
class OrderService:
def __init__(self, repo: OrderRepository):
self.repo = repo # залежить від абстракції
def create_order(self, order):
self.repo.save(order)Використання (впровадження залежності)
python
repo = MySqlOrderRepository()
service = OrderService(repo)
service.create_order("order-1")За потреби:
python
service = OrderService(PostgresOrderRepository())І жодних змін у OrderService.
Чому це дотримання DIP:
- OrderService залежить від абстракції, а не від конкретного репозиторію. Це означає, що бізнес-логіка не прив'язана до MySQL, Postgres чи будь-чого іншого.
- Конкретні реалізації залежать від абстракції, а не навпаки.
MySqlOrderRepositoryіPostgresOrderRepositoryреалізують один контракт. - Можна змінювати інфраструктуру без зміни бізнес-коду. Хочемо перейти на іншу БД? Просто створюємо нову реалізацію.
- Тестування стає простим. Можна підставити мок:
python
class FakeRepo(OrderRepository):
def save(self, order):
print("Фейкове збереження")- Архітектура стає гнучкою і розширюваною.
Підсумок
У цьому прикладі DIP дотримано: модуль високого рівня (OrderService) залежить лише від інтерфейсу (OrderRepository), а конкретні деталі реалізуються окремо і підставляються ззовні.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.