Как стать автором
Обновить

Комментарии 12

С критикой фабрик вы свернули куда-то не в ту сторону.


Во-первых, первый пример из документации — это анти-пример, поясняющий как нельзя делать:


However, the above code is an example of an anti-pattern. This will work, and you can use the container to get access to all other classes in your app, however if you do this you will not really be taking advantage of the power of dependency injection. This is known, by the way, as Service Locator Pattern.

Во-вторых, если класс знает о фабрике, а фабрика знает о контейнере — это еще не означает что класс знает о контейнере. Да, явное использование классов из библиотеки означает что теперь нельзя так просто взять и сменить библиотеку, но SRP при этом не нарушается!


Ну а если не нравится использование конкретных классов как зависимостей — то вот подходящий раздел: Using IFactory directly. Такую фабрику потенциально можно использовать и вовсе без контейнера.


То же самое касается и ITickable — да, контейнер теперь знает про все ITickable-компоненты. Но интерфейс остается просто интерфейсом, и никто не мешает его использовать и без контейнера.

Во-вторых, если класс знает о фабрике, а фабрика знает о контейнере — это еще не означает что класс знает о контейнере. Да, явное использование классов из библиотеки означает что теперь нельзя так просто взять и сменить библиотеку, но SRP при этом не нарушается!

Того, что фабрика знает о контейнере уже достаточно, чтобы делать вывод о завязке на контейнер и о том, что контейнер начинает управлять кратко-срочными зависимостями, чего делать не должен.
Использование ITickable и IFactory также завязывает проект на контейнер, в силу того, что код этих интерфейсов реализован в коде Zejnect.
Касаемо ITickable — можно оставить интерфейс и его можно использовать без контейнера, но тогда нужна собственная реализация класса, который будет обрабатывать все ITickable
В чем принципиальное отличие краткосрочных зависимостей от долгосрочных и почему управление первыми — плохо?
Управление краткосрочными зависимостями по средством контейнера приведет к частому внедрению самого контейнера по множеству фабрик, которые вы используете, что приводит к более сильной завязке на код контейнера. И это приведет к тому, что вы никак не сможете ограничить применение контейнера корнем компоновки. Если контейнер начинает все чаще появляться в коде самого приложения это, в конечном итоге, приводит к тому, что у контейнера появится еще больше ответственностей, а также чревато плавным переходом от контейнера к локатору сервисов.
Я не утверждаю, что использование контейнера в 2-3 фабриках по проекту приведет все к бедственному состоянию, но это уже сигнал о том, чтобы задуматься
Если контейнер начинает все чаще появляться в коде самого приложения

… но ведь он при подходе с фабриками не будет появляться в коде приложения за пределами Composition Root.


а также чревато плавным переходом от контейнера к локатору сервисов

Не могу представить ни одного сценария, когда увеличение использования фабрик плавно превращается в сервис-локатор. Это два совершенно разных паттерна.

… но ведь он при подходе с фабриками не будет появляться в коде приложения за пределами Composition Root.

Получается, что сама фабрика зашита в контейнер, пусть и неявно.
Не могу представить ни одного сценария, когда увеличение использования фабрик плавно превращается в сервис-локатор. Это два совершенно разных паттерна.

Передача контейнера в фабрику в данном контексте выступает как первый шаг к тому, чтобы позволить себе передать контейнер в другие классы. Но ему и в фабрике не место.
Почему это вдруг первый шаг-то? Код фабрики не является кодом приложения.
Ребята, я понимаю, вы знаете что такое Внедрение зависимостей, но как-то принята в русских статьях аббревиатура DI, она не переводится никем в русских ресурсах. Или хотя бы дайте понятную расшифровку аббревиатуры. А то сложно было поять, что же такое ВЗ.
Спасибо, за комментарий, поправил
Да, Zenject избыточен, да, можно использовать его не по феншую — так любую библиотеку можно использовать не так, как задумано. Проблема только в криворукости разработчиков и их опыте.
Статья по сути своей хороша лишь тем, что указаны проблемы Zenject с точки зрения DI. Написано, что плохо, и как делать не стоит. Но не написано, как делать стоит в каждом конкретном случае)
Все рекомендации в программировании в основном и состоят из того как делать не стоит.
Как стоит делать в каждом конкретном случае описать невозможно.

Мне повезло познакомится с Simple Injector в качестве первого контейнера, рекомендую почитать основные принципы (англ.). Идеальное руководство чтобы правильно понять контейнеры.

Design Principles
Design Decisions

Кстати он еще и внутри адекватно сделан и поэтому быстро работает (advanced)
Simple Injector Pipeline

ps: не спешите переводить проект на юнити на Simple Injector, он использует кодогенерацию и не заведется под iOS
Проблема только в криворукости разработчиков и их опыте.

Знать бы где упасть, да соломки бы подстелить. Узнать о своей криворукости зачастую получается уже собрав все грабли.

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

Публикации

Истории