TGStat
TGStat
Type to search
Advanced channel search
  • flag English
    Site language
    flag Russian flag English flag Uzbek
  • Sign In
  • Catalog
    Channels and groups catalog Regional compilations Thematic compilations Платные каналы Search for channels
    Add a channel/group
  • Ratings
    Rating of channels Rating of groups Posts rating
    Ratings of brands and people
  • Analytics
  • Search by posts
  • Telegram monitoring
  • Promotion
    Advertising through Yandex Business Advertising in channels through TGStat Agency Advertising on TGStat.ru website
Советы разработчикам (python и не только)

7 Jan 2024, 23:40

Open in Telegram Share Report

Dependency Injection

Принцип внедрения зависимостей, будучи достаточно простым, концептуально оказывается часто неочевидным.

Суть его в том, что когда у нас одному из объектов требуется другой, то он не создает или ищет его сам, а принимает извне. Например, если вашей функции нужно соединение с БД, то она не должна ни импортировать его, ни брать из глобальной переменной, ни создавать сама. Ей это соединение должны передать.

Само собой, какой-то код будет создавать эти зависимости, и тут мы стараемся отделять его от кода, использующего их. Благодаря этому:
• во-первых, делаем этим зависимости более явными;
• во-вторых, можем управлять тем, будет ли использован один экземпляр зависимости или разные;
• в-третьих, можем использовать один и тот же код с разными реализациями зависимостей.

Представьте, что вашему классу нужны некоторые параметры конфигурации, которые влияют на его поведение, и вы хотите протестировать разные варианты. Если бы класс сам грузил настройки, то вам пришлось бы в тестах учитывать, как именно он это делает, и возможно манипулировать теми объектами, которые обычно не меняются в процессе работы программы. Если же код класса получает эти настройки извне, то вы просто сделаете несколько вызовов с разными настройками. И даже если код класса изменится, тесты останутся корректными.

Можно выделить три способа внедрения зависимостей:
1. Внедрение через параметры функции/метода. Просто передаем зависимость как ещё один параметр:

 def clear_users(cursor):
cursor.execute("TRUNCATE users;")

cursor = connection.cursor()
clear_users(cursor)
clear_users(cursor)

2. Внедрение через параметры конструктора:

 class UsersDAO:
def __init__(self, cursor):
self.cursor = cursor
def clear_users(self):
self.cursor.execute("TRUNCATE users;")

dao = UsersDAO(connection.cursor())
dao.clear_users()
dao.clear_users()

3. Внедрение через атрибуты экземпляра (см. так же двухфазная инициализация):

 class UsersDAO:
def clear_users(self):
self.cursor.execute("TRUNCATE users;")

dao = UsersDAO()
dao.cursor = connection.cursor()
dao.clear_users()
dao.clear_users()

Популярные заблуждения:
• Это что-то из мира java, в моем языке его нет. Неверно. Для того чтобы в языке можно было реализовать внедрение зависимостей, необходимо лишь иметь возможность передать ссылку на функцию или на объект. Это применимо как к Javascript и Python, так и к C и Golang.
• Он нужен только большим enterprise приложениям. Скорее, он критичен для больших приложений. Небольшие приложения без автоматических тестов могут действительно существовать без внедрения зависимостей, но по мере усложнения необходимость в нем будет все более и более заметна.
• Для него нужен специальный фреймворк/IoC-контейнер. Как показано выше, для DI не нужен никакой фреймворк, это возможность вашего языка. Фреймворки лишь помогут упростить построение графа зависимостей (когда у вас достаточно много разных связанных объектов) или решить какие-то прикладные задачи связанные с этим. Хуже, что неосторожное использование таких фреймворков может наоборот лишить вас DI, хотя вы будете думать что это не так.

Дополнительные материалы:
• https://martinfowler.com/articles/dipInTheWild.html
• https://www.jamesshore.com/v2/blog/2006/dependency-injection-demystified

12.7k 41 162 112 152
Catalog
Channels and groups catalog Channels compilations Search for channels Add a channel/group
Ratings
Rating of Telegram channels Rating of Telegram groups Posts rating Ratings of brands and people
API
API statistics Search API of posts API Callback
Our channels
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Read
Академия TGStat Telegram Research 2019 Telegram Research 2021 Telegram Research 2023
Contacts
Справочный центр Support Email Jobs
Miscellaneous
Terms and conditions Privacy policy Public offer
Our bots
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot