На странице Википедии, посвященной внедрению зависимостей, раздел о недостатках говорит нам об этом:
Внедрение зависимостей увеличивает связь, требуя от пользователя подсистемы обеспечивать потребности этой подсистемы.
со ссылкой на статью против внедрения зависимостей .
Внедрение зависимостей заставляет класс использовать интерфейс вместо конкретной реализации. Это должно привести к снижению сцепления , нет?
Чего мне не хватает? Как внедрение зависимостей увеличивает связь между классами?
dependency-injection
coupling
BЈовић
источник
источник
Ответы:
Внедрение зависимостей уменьшает связь между классом и его зависимостью. Но это увеличивает связь между классом и его потребителем (поскольку потребителю требуется больше информации для его создания) и зависимостью и его потребителем (поскольку потребитель должен знать зависимость для использования).
Очень часто это хороший компромисс. Класс не должен знать подробностей о своих зависимостях за пределами интерфейса, и приложение должно нести ответственность за связывание определенных фрагментов кода вместе.
источник
Предположим, у вас есть подсистема,
S
которая зависит от соединения с базой данныхD
. Без внедрения зависимости существует относительно тесная связь междуS
иD
, потому чтоS
нужно знать, как использоватьD
и как ее создавать. Однако остальная часть системы может блаженно не знать об этой зависимости междуS
иD
.С внедрением зависимостей связь между
S
иD
становится более свободной, потому что вы удаляете изS
знания, как создатьD
.S
просто нужно знать, как его использовать. Повышенная общая связь обусловлена тем фактом, что другие части системы теперь должны знатьD
и, возможно, как ее создать. Степень этого увеличения связи зависит от того, как зависимостьD
вводится вS
:S
нуждается в зависимостиD
и, возможно, в знаниях, как его создать.S
через которыйD
вводится метод, нуждается в зависимостиD
и, возможно, в знаниях о том, как его создать.В любом случае, количество классов, которое зависит от
D
увеличения, и знания о том, как создатьD
все еще должны присутствовать где-то в системе. Это создает общее увеличение сцепления.источник
S
должен предоставить фабрикуD
, что означает, что он должен знать, чтоS
используетD
(или, по крайней мере, какой-то его интерфейс).Я категорически не согласен, что это увеличивает сцепление.
Без внедрения зависимости у вас есть тесная связь между подсистемой и конкретной реализацией зависимости.
С внедрением зависимости вы отсоединили подсистему от реализации зависимости.
Утверждение о том, что это увеличивает связь между потребителем и этой подсистемой, ОЧЕНЬ сомнительно, поскольку подразумевает, что потребитель теперь тесно связан с зависимостью, требуемой подсистемой. Все это означает, что вы пишете тесно связанный код, который связывает вашего потребителя с зависимостью. В идеале ВСЕ ваш код отделен.
Конструктор Инъекция:
Разрешение зависимостей обрабатывается контейнером внедрения зависимостей или фабрикой. Потребитель может получить конкретную реализацию подсистемы из контейнера ввода зависимостей или с фабрики.
Потребителю не нужно знать, как выглядит конструктор подсистемы. Нет связи с зависимостью подсистемы.
Метод инъекции:
То же, что и инъекция в конструктор, за исключением того, что теперь потребителю нужно получить конкретный экземпляр зависимости из контейнера или фабрики (или даже вставить его метод / конструктор) и внедрить его в метод. Опять же, потребитель не связан с конкретной реализацией зависимости.
TL; DR Наихудший случай для внедрения зависимостей в подсистеме - это то, что связь сдвинута на потребительский код. НЕТ ОБЩЕГО УВЕЛИЧЕНИЯ МУФТЫ.
В лучшем случае все системы теперь слабо связаны, а внедрение зависимостей контролируется через контейнеры или фабрики внедрения зависимостей.
источник