LINUX.ORG.RU

Dependency Injection

 ,


0

2

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

Если твой DI движок это позволяет, то внедряй классы. Плодить интерфейсы ради интерфейсов смысла нет. В крайнем случаем, если это java, то все можно исправить рефакторингом.

foror ★★★★★
()

проблемы статики они такие проблемы, да.

В JavScript такого не было

Зы. Покажите мне контейнер, который бы мог проводить инжекцию без интерфейсов

EnterpriseMobility
()
Ответ на: комментарий от EnterpriseMobility

проблемы статики они такие проблемы, да.

Вообще, понимаешь, что такое DI?

В JavScript такого не было

Понятно, жертва современного интернет образования программированию

Зы. Покажите мне контейнер, который бы мог проводить инжекцию без интерфейсов

Tapestry IOC - https://tapestry.apache.org/ioc.html

foror ★★★★★
()
Ответ на: комментарий от foror

Вообще, понимаешь, что такое DI?

ОК, расскажи мне, как я путаю понятия IoC и DI. Хотя в реальной жизни они используются совместно.

- Когда поставщик чего-то там начинает зависеть от потребителя - это IoC.

- Когда потребитель ресурса не заботится о выборе/создании поставщика ресурса - это DI. потребитель знает только про интерфейс.

Т.к. в JS слабой типизация, то DI там реализуется тупой передачей поставщика ресурсов как параметра конструктора.

Т.е. мы пишем:

init(db) {

// здесь мы используем db

}

Tapestry IOC

не увидел там ни строчки кода.

EnterpriseMobility
()
Ответ на: комментарий от EnterpriseMobility

наконец-то ты соотовествуешь своему уровню. и никаких деревьев

anonymous
()

У автора ООП головного мозга

Синглтоны же! А ещё лучше обструктную фабрику синглтонов! Главное потом моков побольше сделать, чтобы написать юниттест.

P.S. топикстартер, ты школьник? Вроде все вменяемые девелоперы подобное ооп-шное дерьмо съели и высрали ещё в школе.

peacelove
()
Ответ на: комментарий от pozitiffcat

что об этом думают люди?

вот я и написал тебе что думают люди

Роберт Мартин бизнесмен и графоман который стрижёт на консалтинге капусту с лохов. Инженер из него как из говна пуля.

peacelove
()

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

Debasher ★★★★★
()
Последнее исправление: Debasher (всего исправлений: 1)

Общего решения нет.

Deleted
()

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

Ага, то есть если бы тест писался, то такой вопрос бы и не возник? Ну что ж, если не планируется делать более одной реализации и если не требуется подменять реализацию в тесте, то наверное можно обойтись и без интерфейса, да.

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

CARS ★★★★
()
Ответ на: комментарий от CARS

Шизохрения на марше. Если у тебя есть класс в который ты подставляешь стратегию (или конфигурируешь его), то зачем тебе на этот класс еще городить интерфейс?

Deleted
()

Можно и конкретные классы в твоем случае.

dizza ★★★★★
()

Есть два главных подхода

1) Интерфейс необходим. Этот подход более адекватен для сохранения бинарной совместимости библиотеки, где нельзя просто пересобрать весь код.

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

vertexua ★★★★★
()
Ответ на: комментарий от CARS

Ну что ж, если не планируется делать более одной реализации и если не требуется подменять реализацию в тесте, то наверное можно обойтись и без интерфейса, да.

Во многих ЯП mocks работают и поверх классов. Например Java. В С++ прийдется обьявлять метод виртуальным, даже если тебе это не нужно, а иногда это невозможно если метод шаблонный. Интерфейсы не улучшают ситуацию в обеих случаях.

vertexua ★★★★★
()
Ответ на: комментарий от f1xmAn

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

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

О ты круто пояснил, интересный ход мыслей. Зачастую, кода пишется корпоративное приложение, нам бинарная совместимость не нужна, мы же не либу пишем. И смысл нам напрягаться и поддерживать вместе с классом еще и сущность «Интерфейс».

pozitiffcat ★★★
() автор топика
Ответ на: комментарий от pozitiffcat

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

vertexua ★★★★★
()
Ответ на: комментарий от EnterpriseMobility

Т.к. в JS слабой типизация, то DI там реализуется тупой передачей поставщика ресурсов как параметра конструктора.

Где код, который осуществляет инъекцию db в init? И каким образом он понимает, какую реализацию db нужно инжекнуть?

Или ты считаешь, что если где-то рядом определишь: «var db = ...», то у тебя уже DI?

foror ★★★★★
()
Ответ на: комментарий от foror

если я внутри init модуля создаю экземпляр класса `MySuperPuperDataBaseInstance` - это уже не DI. Этот модуль хрен ты протестируешь сложнее протестировать.

если я создаю db инстанц ВНЕ модуля и потом передаю его в конструктор - то это я УЖЕ использую DI.

EnterpriseMobility
()
Ответ на: комментарий от EnterpriseMobility

если я создаю db инстанц ВНЕ модуля и потом передаю его в конструктор - то это я УЖЕ использую DI

Да, тяжелый случай. В комментариях к init, хотя бы напишешь публичные методы db для других программистов? Или им придется весь твой модуль изучать (мысленно желая смерти автору)?

foror ★★★★★
()
Ответ на: комментарий от foror

Какой в жопу модуль? db - это монга, couch, level, mysql, oracle. Иди на гитхаб - изучай API.

Или ты мне предлагаешь второй раз эту ИХ API оборачивать собственными объектами?

EnterpriseMobility
()
Ответ на: комментарий от vertexua

Скажи это говнокодерам, которые все методы делают публичными, а ты потом сидишь и думаешь, что из этого реально должно быть публичным и можно использовать, а что - нет.

f1xmAn ★★★★★
()
Ответ на: комментарий от EnterpriseMobility

Ок'ей если db - это монга, то вернемся к началу.

проблемы статики они такие проблемы, да.

Что мне мешает написать в статике:

init(MongoAPI db) {

// здесь мы используем db

}

Или монга, couch, level, mysql, oracle имеют везде один и тот же интерфейс?

foror ★★★★★
()
Ответ на: комментарий от foror

БЛДЖАД, в JS НЕТ интерфейсов, Т.К. оно ДИНАМИЧЕСКИЙ С УТИНОЙ ТИПИЗАЦИЕЙ!

В школе тебя чему учили? иди быдлокодь бегущую строку на HTML 4.

EnterpriseMobility
()
Ответ на: комментарий от foror

Или монга, couch, level, mysql, oracle имеют везде один и тот же интерфейс?

НЕТ. Если меняется база данных, то нужно заново переписывать модуль доступа к данным.

EnterpriseMobility
()
Ответ на: комментарий от EnterpriseMobility

НЕТ. Если меняется база данных, то нужно заново переписывать модуль доступа к данным.

Так какие тогда проблемы со статикой? Если код идентичный?

init(MongoAPI db) {

// здесь мы используем db

}
foror ★★★★★
()
Ответ на: комментарий от Debasher

Спорно. Собеседовал довольно большое количество разработчиков разного уровня, мало кто может сказать что это вообще такое. И про архитектурные подходы не слышали, хорошо если хотя бы слово «паттерн» знают.

f1xmAn ★★★★★
()
Последнее исправление: f1xmAn (всего исправлений: 1)
Ответ на: комментарий от f1xmAn

Я не о том.

Вред SOLID'а не в его концепциях, а то что его бездумно начинают везде применять только запутывая код. Очень осторожно его преподавать и использовать надо.

А про патёрны — уж если, то лучше вместо всяких GoF'ов хотя бы GRASP показыавть

Debasher ★★★★★
()
Ответ на: комментарий от Debasher

В его преподавании и использовании не нужна осторожность, проблема в другом. В том, что многие при написании кода не умеют принимать обдуманные решения, часто делают так просто потому, что их так научили, а не потому, что это нужно в конкретном случае. Это херовые разработчики, а не сложный и опасный SOLID.

f1xmAn ★★★★★
()

YAGNI ;)

Не нужно создавать сущности без особой на то необходимости.

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

Принципы по-простому: кому надо.

anonymous
()

Используете ли вы интерфейсы, когда внедряете зависимость?

Если у этого интерфейса будет больше одной реализации, использую. Иначе — зачем плодить сущности?

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

Даже если буду — mock-фреймворки прекрасно работают с обычными классами.

Legioner ★★★★★
()
Ответ на: комментарий от f1xmAn

Интерфейс это публичный контракт класса, нужно его юзать хотя бы из-за этого.

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

Legioner ★★★★★
()
Ответ на: комментарий от vertexua

А чем второй подход портит бинарную совместимость? Связывание в Java идёт по именам методов. Просто не удаляй и не переименовывай публичные методы, если хочешь сохранить бинарную совместимость и всё.

Legioner ★★★★★
()
Ответ на: комментарий от vertexua

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

С геттерами-сеттерами суть в единообразности. Нет проблем выставлять поля. Нет проблем заменить в будущем поле на геттер-сеттер, если нам доступен код клиента, наверное даже рефакторинг такой есть. Но вот такой код будет выглядеть убого в итоге: point.x + point.getY()

Если бы в Java был синтаксис для вызова геттера, как свойства, тогда было бы шикарно. Но чего-то морозятся они уже 25 лет.

Legioner ★★★★★
()
Ответ на: комментарий от f1xmAn

Скажи это говнокодерам, которые все методы делают публичными, а ты потом сидишь и думаешь, что из этого реально должно быть публичным и можно использовать, а что - нет.

И что им мешает в интерфейс все эти методы высунуть? Разруха, она в головах, а не в публичных методах.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Я говорил о разнице

Toyota car = new Toyota();
car.go();

и

Car toyota = CarFactory.create("toyota");
car.go();

В втором случае о классе Toyota просто не известно клиентскому коду. И если его выпилить и заменить на ToyotaFasterImpl, то всем пофиг.

А вот если все это в одной кодовой базе, то везде если натыкать тойот, то рефакторинг потом не такой страшный, зато вы не городили интерфейсы на каждый чих, не зная, понадобятся они или нет.

И да, я знаю о DI, что мол этот код плохо тестируется. «new» в данном случае просто для упрощения, я вполне считаю нормальным инъекцию классов без интерфейсов.

vertexua ★★★★★
()
Ответ на: комментарий от vertexua

А потом кто-то в бинпостпроцессоре заменит объект на прокси и контекст не подымется, потому что не найдет нужный класс в контексте для инджекшена. А вот если инжектится интерфейс, то найдет.

f1xmAn ★★★★★
()

У тебя вопрос то в чём? Если ты хочешь знать как правильно инжектить, то ответ интерфейсом. А вот если тебе (при наличии удобных средств автоматизации рефакторинга в ИДЕ) лень этим заниматься то ответа у меня нет.

ya-betmen ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.