Russian Qt Forum
Ноябрь 23, 2024, 07:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Dependency injection  (Прочитано 20547 раз)
Bepec
Гость
« Ответ #30 : Сентябрь 02, 2014, 00:40 »

Почитал, впечатлился. В хорошем смысле этого слова.

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

Я пока не вижу задач, ради которых надо вытаскивать из класса нутро.

Возьмём Qt (аки форум всё таки по Qt). QSqlDatabase работает с БД. Через QSqlDriver. А QSqlDriver имеет различные реализации для БД. А вот для удобной инициализации у QSqlDatabase имеется статический метод, вытаскивающий драйвер и создающий нужный нам QSqlDatabase.

Слабая связанность? да.
Простота? да.
Легко в отладке? да.
Переписать под себя? легко.
DI в слабой форме - всё таки да, думаю это DI. А то, что вы показываете нам - больше похоже на преувеличение.

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

update: солидарен с _Bers - такие вещи делаются проще и без DI. Всё равно нам надо прописывать интерфейсы классов, необходимо прописывать зависимости. Обычных классом лучше,потому что там действует принцип инкапсуляции. Когда ты в душе не чаешь что кроется за "QString.replace("\n\r", "haha");", но оно работает. И ты туда присунуть можешь всё, начиная от адреса памяти, заканчивая TCHAR.
« Последнее редактирование: Сентябрь 02, 2014, 00:43 от Bepec » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #31 : Сентябрь 02, 2014, 08:00 »

Код
PHP
class BookStorage
{
   private $db;
   public function __construct(Database db)
   {
       $this->db = db;
   }
 
   public function store(Book $book)
   {
       $this->db->insert(book);
   }
}
 

Вуаля. Мы сделали внедрение зависимости. За громким названием скрывается достаточно простой принцип. Мы "засовываем" один объект внутрь другого, внедряем его. Мы внедряем объект, от которого зависит BookStorage.
Это не вызывает вопросов, но причем здесь "инжекция" - хз. Вот напр метод insert платфомо-зависимый - и мы вынуждены так делать. Или хотим иметь возможность работать с разными типами БД. Ясно что реализацию надо изолировать от клиента.  Тогда чем плохи стандартные подходы - виртуальный базовый класс и/или фабрика?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #32 : Сентябрь 02, 2014, 08:40 »

Я к тому, что настройки должны быть максимально простыми.
А я и не говорю о каких-то сложных настройках:
Код
C++ (Qt)
{
   StorageBackend *stor = cmdLine.contains( "--mysql" )?
                                           MySqlStorage( host, port, user, password ) :
                                           XmlStorage( filename, "UTF-8" );
 
   BookStorage book( stor );
}
 
Настройки просты, но их нужно задать.

Что касается DI - я так и не понял, что это такое, и зачем оно нужно.
Это потому, что он ничем не отличается от стратегии, ну кроме названия.
И в одном и в другом подходе, мы выносим неких функционал из класса, для того что-бы иметь возможность управлять им отдельно.
Записан
Bepec
Гость
« Ответ #33 : Сентябрь 02, 2014, 11:38 »

Т.е. моё утверждение, что это лишь часть паттерна ООП, неизвестно кем выдвинутая в отельный паттерн верно? Улыбающийся
Записан
vregess
Гость
« Ответ #34 : Сентябрь 02, 2014, 21:00 »

А теперь ответьте мне на мой вопрос: Если вы вытащили кишки класса наружу, и свалили мне на голову свою БД, накой чорт мне тогда может быть нужен класс BookStorage?
Так ведь он нужен для операций с хранилищем. Ну добавим в метод insert() еще пару строк, а потом добавим еще метод remove(). И что, ты каждый раз теперь будешь дублировать операции из insert() и remove(), раз смысл в BookStorage пропал? BookStorage теперь содержит только операции с хранилищем и избавлен от разруливания зависимостей при создании этого хранилища.
Да и почему свалили тебе на голову БД, ведь вытаскивание этих "кишок" всего лишь подготовка класса для работы с IoC контейнером. Эти "кишки" затем опять будут спрятаны, но уже в другом месте.

Вот еще одно определение для DI:
Цитировать
Внедрение зависимостей — паттерн проектирования, основная задача которого — отделить поведения объекта от управления его зависимостями

Еще раз повторю, эти "кишки" достаются не тебе, а перемещаются в другую сущность.

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

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


В отличие от "внедрения зависимостей", адепты которой сами толком не могут по простому ответить на вопрос - зачем это нужно.
Так ведь в который раз уже: уменьшить связанность между компонентами, избавление от ручного создания объектов; отделение поведения объекта от управления его зависимостями.

Кстати, в чем вы видите разницу между стратегиями и этим DI?

Все же DI и компания ближе к фабрикам, чем к стратегиям.

Я имел возможность убедиться в этом на собственной шкуре - когда однажды понял, что совершенно напрасно потратил время и усилия на поддержку "тонких настроек", которыми никто никогда так и не воспользовался, потому что "это гимморно слишком, проще взять другой механизм, который из коробки лучше отвечает требованиям".
Ну вот был у тебя неудачный опыт с избыточными сущностями, причем не с DI/IoC, а все-равно это анти-паттерн, причем потом еще оказывается, что

Что касается DI - я так и не понял, что это такое, и зачем оно нужно.
Откуда взялось стойкое мнение, про абсолютную вредность этого паттерна, если нет ясного понимания? Меня вот это удивляет.
Верес тоже хорош, привел ссылку и тут же говорит, что не понял, что написано. Так зачем было вообще ее постить?  Увидел слова "внедрение" и "зависомость"? Так может там описание порнофильма с наркоманами было, а не про DI?

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

Это не вызывает вопросов, но причем здесь "инжекция" - хз.
Ну как причем, показан прием инъекции через конструктор.

Тогда чем плохи стандартные подходы - виртуальный базовый класс и/или фабрика?
Все, что связано с DI/IoC, относится не к изменению поведения, а к переносу ответственности за создание объектов в другое место. Фабрика здесь вполне подойдет, но об отличии фабрики от ID я выше приводил цитату с SO.

Может быть я что-то не так объяснил, раз народ до сих пор чешет репу, зачем это нужно (а может вам оно и не нужно?). Ну давайте вот еще один пример, уже из документации Guice (java): https://github.com/google/guice/wiki/Motivation (англ).

PS я не призываю никого использовать этот паттерн, и не доказываю, что это какая-то панацея от всех бед, что он лучше других подходов. Единственное, что хочется донести, что его называют бесполезным и опасным совсем не заслуженно.
Записан
Bepec
Гость
« Ответ #35 : Сентябрь 02, 2014, 23:07 »

Цитировать
Верес тоже хорош, привел ссылку и тут же говорит, что не понял, что написано. Так зачем было вообще ее постить?  Увидел слова "внедрение" и "зависомость"? Так может там описание порнофильма с наркоманами было, а не про DI?
Вот поэтому и спросил ) Искал незнаю что, нашёл ссылку, попал пальцем в небо и спросил знающих Улыбающийся
Я прочитал, попытался осознать и не понял. Попросил объяснить. Найдёте в этом поведение предъосудительное - пишите, побеседуем Веселый

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

Вот DI. Настоящий и без затей.
Код:
QNetworkReply *	post(const QNetworkRequest & request, QIODevice * data)
Проще выражаясь - метод не создаёт QNetworkRequest и... И всё Улыбающийся
Он имеет зависимость от QNetworkRequest, при этом не управляя его созданием.  

Зачем нужен этот паттерн в практике - для упрощения написания тестов.

Почему многие не могли его понять по вашим объяснениям - вы мешаете всё в кучу. Фабрика остаётся при этом фабрикой. Она в DI не нужна. Её как и любой другой объект можно использовать, но даёт лишнюю сущность и глобальный объект "знающий всех".  Улыбающийся

Теперь я доволен и это похоже на правду. Правда, т.к. этот паттерн в с++ используется часто, он стал для меня обыденностью Улыбающийся

PS полезность его находится в заоблачной высоте.
« Последнее редактирование: Сентябрь 03, 2014, 01:26 от Bepec » Записан
vregess
Гость
« Ответ #36 : Сентябрь 03, 2014, 05:19 »

Он имеет зависимость от QNetworkRequest, при этом не управляя его созданием.  
Да, ты прав, все так и есть.

вы мешаете DI, фабрики и приписываете чудодейственные свойства этой смеси
...
вы мешаете всё в кучу. Фабрика остаётся при этом фабрикой. Она в DI не нужна
И тут скорее всего ты тоже прав, частично. Наверное лучше было не  упоминать про фабрики, при описании DI, это больше к IoC относится (реализация IoC есть в шестой части в серии постов, которые я в самом начале приводил). Запутал народ получается. Просто DI можно реализовать при помощи фабрик, это один из вариантов.
Вот тут есть про DI - fabric http://stackoverflow.com/questions/557742/dependency-injection-vs-factory-pattern

там действительно разложено лучше
Значит я плохая объяснялка.
Записан
Bepec
Гость
« Ответ #37 : Сентябрь 03, 2014, 07:03 »

Ну и хорошо, что всё хорошо кончилось. Спасибо тебе за то, что потратил на нас своё время Веселый

PS становитесь объяснялкой получше Веселый
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #38 : Сентябрь 03, 2014, 13:49 »

Значит я плохая объяснялка.
Вовсе нет, просто иногда слишком категоричны Улыбающийся Мне ближе точка зрения _Bers - беда когда паттерн (любой) начинает применяться без оснований, просто потому что паттерн - это (якобы) хорошо. Очень быстро паттернист так задрочит код что работать с ним станет невозможно. Но все равно, спасибо за разъяснения. 
Записан
vregess
Гость
« Ответ #39 : Сентябрь 03, 2014, 17:19 »

Мне ближе точка зрения _Bers - беда когда паттерн (любой) начинает применяться без оснований, просто потому что паттерн - это (якобы) хорошо. Очень быстро паттернист так задрочит код что работать с ним станет невозможно.
Так я с этим согласен и никого не призывал использовать паттерны, просто пришлось ссылаться на общепринятые названия, может поэтому кажется что я "паттернист" или сую их везде.

Точка зрения _Bers была:
Цитата: _Bers
Иньекция зависимостей - анти-паттерн
Лишь с этим утверждением я не согласен. А обо всем остальном я вроде и не заикался.
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.184 секунд. Запросов: 23.