Dependency injection и envy зависимости.

Yoskaldyr

.
Партнер клуба
Заголовок конечно странный но хз как более правильно feature envy перевести на русский. То что нашел это завистливые функции, но это не совсем то, а завистливые зависимости, это как-то вообще молочное молоко.

В чем конкретно вопрос вопрос.
В идеале если использовать полноценный Dependency injection через параметры конструктора полностью для всех классов что будут использоваться для полного предотвращения feature envy, то в самом начале например сразу после определения экшена заинстанцировать или все классы что будут или могут использоваться дальше или все их фабрики. Т.е. всю цепочку зависимостей. И тут все красиво, но не нравится только то, когда если дальше есть условные разветвления (а их может быть довольно много на сложной логике), то получается довольно много ненужных объектов которые даже не будут использоваться в 90% случаев. Да и конфиг получается страшноватый, независимо от конкретного DI контейнера.

И что я заметил перелопатив большое количество более менее больших опенсорсных проектов на гитхабе. Больше половины вообще забили на DI и на feature envy, клепают создание классов через обычный new и без каких либо проблем юзают различную статику из других классов (не фабрики), а остальные херачат все через сервис локатор (да это "горячо мной любимые" бессмысленные сервисы, да DI контейнер, но по факту такое же гуано как и без него). И я не встретил не одного реального приложения где было бы реализовано полноценное DI с минимальным feature envy для большинства классов.

Т.е. в идеале хотелось бы чтобы все классы использовали только те зависимости что им передали в конструкторе, но я пока не встретил ни одного проекта который бы смог это реализовать. И поэтому вопрос, а возможно ли это в большом приложении? И стоит ли вообще с этим заморачиваться? Или полноценное DI только для небольших участков кода, а так и сервис локатора хватит?
 

WMix

герр M:)ller
Партнер клуба
то получается довольно много ненужных объектов которые даже не будут использоваться в 90% случаев.
возможно это и есть проблема?
хз как более правильно feature envy перевести на русский
возможно я чтото не правильное нашел, напоминает эту проблему
 

Вурдалак

I'd like to model your domain
К гадалке не ходи — SRP нарушается.

Покажи один такой класс, где 90% зависимостей не используются.
 

Yoskaldyr

.
Партнер клуба
Да, это очень близко. Сервис локатор или вызов статик методов из другого класса (за редким исключением) или просто new - это ask. DI через конструктор - tell.
Вот когда куча ask в классе - это feature envy

возможно это и есть проблема?
Ну если есть одна конкретная команда/экшн и в идеале в него уже должна передаться вся цепочка зависимостей. Это не значит что все 20-30 классов что будут использоваться именно в экшене - в экшене 2-3 класса, в них еще по паре и т.д. по цепочке (модели, сервисы, ентити, форматтеры и т.д.). Т.е. каждый класс выполняет свое небольшое дело. Но до выполнения этого дела все может и не дойти, т.к. не прошла какая-то валидация внутри бизнес логики и т.д. И вот проблема в том что при инициализации через конструктор все должно быть проинициализировано значительно раньше какой либо бизнес валидации.
 

Yoskaldyr

.
Партнер клуба
Тогда если кто знает пример кода где все сделано очень красиво в плане DI (не зависимо от DI контейнера), дайте ссылку плз.
 

Yoskaldyr

.
Партнер клуба
Покажи один такой класс, где 90% зависимостей не используются.
Ну если есть одна конкретная команда/экшн и в идеале в него уже должна передаться вся цепочка зависимостей. Это не значит что все 20-30 классов что будут использоваться именно в экшене - в экшене 2-3 класса, в них еще по паре и т.д. по цепочке (модели, сервисы, ентити, форматтеры и т.д.).
Т.е. не прямая передача всех 20 зависимостей в 1 класс, а сумма всех зависимостей всех дочерних классов по цепочке.
Но т.к. это зависимость через конструктор, то проинициализировано должно все быть сразу при внедрении первых 2-х или 3- зависимостей в первый класс
 

Вурдалак

I'd like to model your domain
Ну а зачем пользоваться «экшенами» тогда?

А что-то кроме контроллера есть? А то реально это уже в печенках.
 

Yoskaldyr

.
Партнер клуба
Да не важно что там контроллер, команда, команд хандлер, обработчкик роута (даже в виде кложуры) или еще что. им нужны зависимости и нужно передавать в конструкторе или параметрами (для кложуры) явно. Если класс лезет куда то сам или создает сам, т.е. ask, а не tell, то это не DI. И если полноценный DI, то создавать надо всю започку зависимостей для всех классов что будут использоваться.

@Вурдалак Покажи код где красиво. А то все говорят - делайте, а кода в реальных примерах и нет.
Частичное DI встречается, а вот так чтобы хотя бы на 90% в реальных проектах - нет.
 

Вурдалак

I'd like to model your domain
@Вурдалак Покажи код где красиво. А то все говорят - делайте, а кода в реальных примерах и нет.
Частичное DI встречается, а вот так чтобы хотя бы на 90% в реальных проектах - нет.
лол.
Во дворе так будешь на понт брать.
 

Yoskaldyr

.
Партнер клуба
Во дворе так будешь на понт брать.
Не, ну ты реально специалист, но твое эго тебе явно мешает... соответсвенно и такие посты...

Я не просто так спросил. Я пересмотрел уйму говна за последнее время. Гитхаб еще та свалка... И есть проблема - сцуко никто не юзает нормально DI в реальных проектах (по крайней что есть на гитхабе). Именно насчет этого я и спрашиваю.
А тут сразу на понт... Я не говорю что DI не нужен - он реально нужен. Я спрашиваю кто и как решает, потому что на практике никто никак не решает. и это сцуко статистика и со статиской сцуко не поспоришь!
 

Yoskaldyr

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

Все всегда упирается в нюансы. 100% всех примеров/готовых продуктов используют DI максимум на 50%, остальное прямое создание объектов внутри или через сервис локатор (я молчу у прямом вызове различной статики).

Т.е. вопрос вообще тупо простой, какого х*****, ведь DI и его реализации - это самая примитивная вещь по сравнению с другими, но этот примитивизм практически не используется в реальных продуктах хотя бы на 80%????

P.S. @Вурдалак А то похоже на анекдот про каламбур насчет графа Монте-Кристо/д'Артаньяна...

P.P.S. Я реально хочу посмотреть на код более менее зрелого продукта написанный нормально, а то всегда отговорка: "а что вы хотели это же легаси..."
 

jonjonson

Охренеть
Вообще наличие дерева зависимостей не свидетельствует о создании всех этих объектов при загрузке приложения.
Обычно используется отложенный вызов. Только гарантированно используемые объекты могут создаваться сразу (например подключение к БД).
Само же определение зависимостей не создает проблем с производительностью.

Как реализуется можно посмотреть например тут http://php-di.org/
 

jonjonson

Охренеть
Все всегда упирается в нюансы. 100% всех примеров/готовых продуктов используют DI максимум на 50%
Всегда есть причины любого явления. И лень, и целесообразность, и организация процесса разработки (влияющая на качество кода) и т.д.
Это нормально. И чего так переживать?
 

Yoskaldyr

.
Партнер клуба
Вообще наличие дерева зависимостей не свидетельствует о создании всех этих объектов при загрузке приложения.
Я не говорил о создании всех объектов. Я говорил о создании всех объектов в цепочке зависимостей при создании первых 2-х или 3-х объектов для первой инъекции. Это немного не одно и тоже что и создание всех зависимостей вообще.
Само же определение зависимостей не создает проблем с производительностью.
Я нигде ничего не говорил об производительности определения :)
 

jonjonson

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

jonjonson

Охренеть
Примеры используемых вами или кем-то экскрементов озвучите?
 

Yoskaldyr

.
Партнер клуба
@jonjonson Да абсолютно все что есть на гитхабе в плане готовых продуктов ecommerce/blogs/cms/crm/еtс

Вообще то я не встречал такого, чтобы порождались все объекты зависимые от данного.
Под зависимостью я понимаю не абстрактно как-то зависимые, а прямо зависимые по конструктору.

Т.е. нельзя создать класс A если у него в конструкторе зависимость от классов B и C, у которых в конструкторах зависимости от BA, BB и CA, CB соответственно без создания этих всей этой цепочки классов. Даже если брать всего 2 зависимости у класса и 4 уровня вложенности то уже 16 классов в худшем случае, а если 5 уровней вложенности, то 32 класса.
 

Yoskaldyr

.
Партнер клуба
Примеры используемых вами или кем-то экскрементов озвучите?
как я искал - тупо гуглил
(Symfony|Laravel|Zend) (ecommerce|shop|blog|cms)
ну заодно и русскоязычные варианты
Это если по простому, так же в результатах всегда вылазило что-то похожее.

P.S. Также не стоит забывать что я спрашивал в самом начале насчет feature envy, т.к. там где более менее есть DI, то feature envy зашкаливает
 

jonjonson

Охренеть
Уже только посмотрев на Laravel мы видим Deferred Providers
Если посмотреть на Symfony и Zend, то они, по моему, используют http://php-di.org/ , но возможно с обертками.
В нем так же все правильно.
Про всякие ecommerce|shop|blog|cms разговаривать смысла нет. С таким же успехом можно заявлять, что 99% людей идиоты.

Т.е. нельзя создать класс A если у него в конструкторе зависимость от классов B и C, у которых в конструкторах зависимости от BA, BB и CA, CB соответственно без создания этих всей этой цепочки классов. Даже если брать всего 2 зависимости у класса и 4 уровня вложенности то уже 16 классов в худшем случае, а если 5 уровней вложенности, то 32 класса.
Я вас как-то не понимаю. Если что-то для чего-то нужно, то это мы создаем.
Если не нужно то нет.
Или вы с этим не согласны?
 
Сверху