Comments 25
Так все-таки, как в вашем «решении» создаются новые экземпляры нужных пользователю классов?
0
Существенным минусом IoC-контейнера, на мой взгляд, это отсутствие авто-дополнений в IDE. Может вы как то решили эту проблему?
+1
Проблема с автодополнением решается очень просто c помощью специальной аннотации
/* @var $adapter \Zend\Db\Adapter\Dapter */
$adapter = $this->getServiceLocator()->get('db-adapter');
0
Немного не понял преимуществ идеи.
> Отлично, а что если какой-нибудь другой программист захочет вместо файлов использовать базу данных? Для этого ему нужно создать класс DatabaseStorage, реализовать интерфейс StorageInterface и заменить все вхождения FileStorage. Но изменение библиотеки сулит проблемы с её обновлениями.
Какие именно проблемы появляются?
И если ранее в конструктор передавался интерфейс, я после удачной компиляции более менее буду уверен в корректности программы. Передача строки не гарантирует ничего. Тем более, что с ленивой загрузкой это обнаруживается только во время выполнения.
> Отлично, а что если какой-нибудь другой программист захочет вместо файлов использовать базу данных? Для этого ему нужно создать класс DatabaseStorage, реализовать интерфейс StorageInterface и заменить все вхождения FileStorage. Но изменение библиотеки сулит проблемы с её обновлениями.
Какие именно проблемы появляются?
И если ранее в конструктор передавался интерфейс, я после удачной компиляции более менее буду уверен в корректности программы. Передача строки не гарантирует ничего. Тем более, что с ленивой загрузкой это обнаруживается только во время выполнения.
+1
И если ранее в конструктор передавался интерфейс, я после удачной компиляции более менее буду уверен в корректности программы. Передача строки не гарантирует ничего.
Вот именно поэтому в адекватных реализациях IoC используются не магические строки, а жесткая привязка к типу (с проверкой периода компиляции).
Тем более, что с ленивой загрузкой это обнаруживается только во время выполнения.
Обычно эта проблема решается юнит-тестами на контейнер. Но муторно.
0
Немного не понял преимуществ идеи.
В чем преимущества самого IoC, я, если можно, рассказывать не буду. Идем дальше.
Для того, чтобы реализовать IoC, нам нужно откуда-то брать все зависимости. Эти зависимости могут (а) иметь свои зависимости и (б) иметь свой жизненный цикл.
IoC имеет две основных реализации: Service Locator (SL) и Dependency Injection (DI). Первую я искренне не люблю (а многие считают ее антипаттерном), вторая более требовательна к контрактам. Проблема «зависимостей зависимостей» возникает только во втором из них, проблема жизненного цикла — в обоих.
Какие именно проблемы появляются?
Во-первых, FileStorage мог создаваться по одному на каждый экземпляр потребителя, а DatabaseStorage — быть общим (ну или наоборот; проблема жизненного цикла). Это значит, что вы не сможете просто заменить один конструктор на другой, вам придется заменять конструктор на вызов синглтона.
Во-вторых, у FileStorage один набор собственных зависимостей (которые учитываются при создании), а у DatabaseStorage — другой (проблема зависимостей зависимостей). Это тоже означает, что простой S&R не поможет. Более того, для каждой из этих зависимостей все эти проблемы повторяются заново, и, как следствие, общее количество проблем растет по экспоненте.
Использование DI-контейнера (или специализированного SL вместо обобщенной фабрики/реестра) сводит эти проблемы на нет. При создании объекта через DI-контейнер (или запросе его у SL) все дерево зависимостей объекта создается автоматически, при этом учитывается ассоциированный с каждым объектом жизненный цикл.
Плюс к этому у вас есть единая (более того, конфигурируемая в рантайме, хоть я этого и не люблю) точка контроля того, какие сервисы используются приложением, что упрощает его модификацию.
0
IoC приколен, но вот что не нравится — это концентрация сложности в конфигах, которые к тому-же plain-text`ом пишутся без code-completion`а и проверок.
Хотя и есть спец-инструменты, которые помагают это всё организовать, однако вот этот момент напрягает.
М.б. этот момент надо уже решать на след. уровне и развивать языки программирования. И возможно какие-то языки уже позволяют это делать. Ruby/python так умеют?
С другой стороны это пожелание а-ля курица-яйцо :)
Хотя и есть спец-инструменты, которые помагают это всё организовать, однако вот этот момент напрягает.
М.б. этот момент надо уже решать на след. уровне и развивать языки программирования. И возможно какие-то языки уже позволяют это делать. Ruby/python так умеют?
С другой стороны это пожелание а-ля курица-яйцо :)
0
IoC приколен, но вот что не нравится — это концентрация сложности в конфигах, которые к тому-же plain-text`ом пишутся без code-completion`а и проверок.
А не надо приравнивать конфиги к IoC. Можно делать IoC без (а) конфигов (б) контейнеров и (ц) с полной проверкой в этапе компиляции.
И язык тут не причем совершенно, IoC умеет столько же, сколько умеет язык, в котором он применяется.
0
Пример в студию или линку — повышу квалификацию Ж)
0
Пример чего? IoC без конфига и контейнера?
Прямо из статьи.
А вообще — вон целая книга про это есть, только не для PHP. Но подходы идентичны.
$user = new User(new FileStorage());
Прямо из статьи.
А вообще — вон целая книга про это есть, только не для PHP. Но подходы идентичны.
-1
Это ни хрена не он — мы тут завязываемся в коде на конкретный класс FileStorage.
Адепты IoC закидают.
Адепты IoC закидают.
0
Эээ… вы, видимо, не вполне понимаете, как работает IoC.
Внутренность
Внутренность
User
должна быть независимой от FileStorage
. А передача снаружи конкретного экземпляра — IoC (через DI, если быть точным) не нарушает. Откуда этот экземпляр взялся — вопрос отдельный совершенно. +1
Может как раз наоборот?
| In software engineering, inversion of control (IoC) is an object-oriented
| programming practice where the object coupling is bound at run time by
| an assembler object and is typically not known at compile time using static analysis.
Уже вечер — о том ли мы говорим?? :)
Я точно помню, что что-то одно из них входит в другое.
| In software engineering, inversion of control (IoC) is an object-oriented
| programming practice where the object coupling is bound at run time by
| an assembler object and is typically not known at compile time using static analysis.
Уже вечер — о том ли мы говорим?? :)
Я точно помню, что что-то одно из них входит в другое.
0
Вы просто добавили ещё одну абстракцию, чтобы заложиться на возможные изменения. Вроде того:
— Что если в будущем мы захотим изменить X? Давайте задавать X через переменную/константу/параметр.
Это хороший универсальный приём. Мастерство разработчика, правда, заключается не в том, чтобы его применить, а в том, чтобы знать когда применять, а когда нет.
— Что если в будущем мы захотим изменить X? Давайте задавать X через переменную/константу/параметр.
Это хороший универсальный приём. Мастерство разработчика, правда, заключается не в том, чтобы его применить, а в том, чтобы знать когда применять, а когда нет.
-1
Sign up to leave a comment.
Разработка архитектуры приложения с использованием инверсии зависимости