Вопрос по ООП синтаксис

Absinthe

жожо
Вурдалак, я бы назвал такой подход SL: класс запрашивает объекты по их идентификатору в контейнере. Прямо в том коде, который ты показал.
Если убрать эти аннотации, то будет DI.
 

MiksIr

miksir@home:~$
Т.е.
PHP:
__construct(Interface $foo) { }
- это DI.

А
PHP:
/**
* @param Interface $foo
*/
__construct($foo) { }
- это не DI, а внезапно SL :)

Прикольно =)
 

MiksIr

miksir@home:~$
MiksIr, если у тебя 10 параметров в конструкторе, то ты сразу видишь, что написал ерунду. А с @Inject-ами выглядит вроде и ничего.
Приучи себя видеть ерунду когда много инжектов и все ;) А желающего наговнокодить и конструктор не остановит.
 

MiksIr

miksir@home:~$
Ага, т.е. оба DI?
PHP:
/**
* @param Interface $foo
*/
__construct($foo) { }
- это все же DI
А
PHP:
/**
* @injectable
* @var Interface
*/
public $foo
- а это уже SL?
 

WMix

герр M:)ller
Партнер клуба
смотри на это как на коментарий
PHP:
$builder->useAnnotations(false);
и вроде опять DI
 

Sufir

Я не волшебник, я только учусь
Может не очень в тему вклинюсь, не пинайте сильно... Очень туго у меня с этими вещами. Из беседы/спора сложилось такое представление:
- если код сам знает как получить у контейнера зависимость и запрашивает её (не зависимо от способа) - это SL;
- если некий инжектор знает о зависимостях в коде и устанавливает их, то это DI;

Я прав? Когда читаешь статьи по теме всё выглядит очень стройно, красиво, удобно и понятно. Когда возвращаюсь к реальному коду и проектам - ничерта не ясно становится, как это всё реализовать и применять полноценно. Хотя тема и очень интересна.
 

MiksIr

miksir@home:~$
Если добавить название сервиса @injectable(serviceid), то будет SL, т.к. код запрашивает из контейнера определенный сервис.
А что такое "сервис"? Наверно, какой-то объект все же, да? Но не конкретного класса, а объект с определенным интерфейсом, конечно? Так в чем разница "определенный сервис" и "определенный интерфейс"?
 

MiksIr

miksir@home:~$
Может не очень в тему вклинюсь, не пинайте сильно... Очень туго у меня с этими вещами. Из беседы/спора сложилось такое представление:
- если код сам знает как получить у контейнера зависимость и запрашивает её (не зависимо от способа) - это SL;
- если некий инжектор знает о зависимостях в коде и устанавливает их, то это DI;
Оба о том, как в итоге объект получит свои сервисы.

Сервис локатор - это класс-реестр, который знает о других сервисах. Объект спрашивает нужные сервисы у него. О том, как объекту добираться до сервис-локатора - паттерн не говорит.

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

Кстати, теоретически никто не мешает доставлять сервис-локатор до объекта посредством DI. На практике это, правда, полный бред. По-этому, SL обычно доставляется через паттерн Синглтон.

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

Absinthe

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

Может не очень в тему вклинюсь, не пинайте сильно... Очень туго у меня с этими вещами. Из беседы/спора сложилось такое представление:
- если код сам знает как получить у контейнера зависимость и запрашивает её (не зависимо от способа) - это SL;
- если некий инжектор знает о зависимостях в коде и устанавливает их, то это DI;

Я прав? Когда читаешь статьи по теме всё выглядит очень стройно, красиво, удобно и понятно. Когда возвращаюсь к реальному коду и проектам - ничерта не ясно становится, как это всё реализовать и применять полноценно. Хотя тема и очень интересна.
Прав, а спорим мы в данный момент о том, являются ли аннотации кодом.
Чтобы разобраться - Symfony.

А что такое "сервис"? Наверно, какой-то объект все же, да? Но не конкретного класса, а объект с определенным интерфейсом, конечно? Так в чем разница "определенный сервис" и "определенный интерфейс"?
Сервис - это не класс или интерфейс. Сервис - это конкретный объект. Инстанс.
Тип может не иметь сервисов, а может иметь несколько.
Сервис определяется своим идентификатором.
Вот когда этот идентификатор появляется в коде, то DI превращается в SL, т.к. код говорит, какой именно сервис он хочет из контейнера.
 

fixxxer

К.О.
Партнер клуба
Это такой синтаксис конфигурации, ага.

Тебе станет легче, если глагол «Inject» заменить на существительное? :)
PHP:
/**
* @DI\Arguments({
*    "em" = @DI\Argument("doctrine.orm.entity_manager"),
*    "session" = @DI\Argument("session")
* })
*/
public function __construct(EntityManager $em, SessionInterface $session)
{
    $this->em = $em;
    $this->session = $session;
}

Требования аргументов в конструкторе — это уже требование зависимостей. Если их не передать, то код работать, увы, не будет.
С одной стороны да. С другой, например:

PHP:
class Foo
{

    public static function constructWithDependenciesFromSl(ServiceLocatorInterface $sl)
    {
         return new self($sl->get("doctrine.orm.entity_manager"), $sl->get("session"));
    }

    public function __construct(EntityManager $em, SessionInterface $session)
    {
        $this->em = $em;
        $this->session = $session;
    }
}
Практически то же самое :)
 

whirlwind

TDD infected, paranoid
Ух-ты. Я-то думал мы тут с сингелтонами лет семь назад разобрались раз и навсегда. Но оказывается периодически набигают товарищи, которые страдают неразличимостью функциональных и нефункциональных требований.
 

WMix

герр M:)ller
Партнер клуба
Тогда почему юбы его не удалить, что ему в коде делать?
Это не комментарий, а код.
AOP аннотации ты тоже комментариями назовешь? Они изменяют поведение участка кода полностью.
всеб тебе удалить. для одних это будет инструкция по сборке, для других конфигурация по умолчанию.
аннотации сами по себе ничего не изменяют - нужна библиотечка, другое дело что без этой библиотечки код потерял функциональность, и вероятнее всего будет пустоват и малоинтересен.
 

Redjik

Джедай-мастер
Можно долго извращаться с Аннтациями и автовключением зависимостей из контейнера через рефликсию, но вся фишка DIC теряется, поясню:

В DIC все зависимости расписаны в конфиге или группе конфигов (разбросанных по приложению, но с определенной логикой).
Таким образом, если мы вдруг решили выкинуть или заменить какой-либо сервис, мы можем быстро пробежаться глазами по конфигам и узнать, где этот сервис используется, и что можно случайно сломать.
Вместо поисков в 100500 файлов SL контейнеров и вызовов этого сервиса.

Это один из use case, но для меня - наиважнейший. Можно пробежаться глазами по конфигу и у тебя вся архитектура перед глазами.
В том же Ларавел, зависимости могут включатся не напрямую через конфиг, а через магию и рефлексию по тайпхинтингу... и это жесть имхо.
 

AmdY

Пью пиво
Команда форума
В DIC все зависимости расписаны в конфиге или группе конфигов (разбросанных по приложению, но с определенной логикой).
ну, ну. а я буду страдать со свои хоткеем в IDE на find usage и лишу себя долгого эротического путешествия по иерархиям конфигов и проведу это время за скучным распитием пива.

У меня на работе проект на laravel, но делался с претензиями на лучшие практики, а на реальной практике подтверждает "Благими намерениями вымощена дорога в ад". Получилось настолько ужасно, что даже попытка двухнедельного рефакторинга пошла проекту скорее во вред, нежели сделала лучше. Конфиги с зависимосятями одно из таких мест, теперь я для других проектов всегда использую фасады, они прекрасны на практике, удобно использовать в коде, удобная навигация, удобно перегружать, а тесты становятся мягкими и шелковистыми. ide_helper не такой уж большой минус за все эти блага.
 

Absinthe

жожо
ну, ну. а я буду страдать со свои хоткеем в IDE на find usage и лишу себя долгого эротического путешествия по иерархиям конфигов и проведу это время за скучным распитием пива.
Не найдешь все.Дофига случаев, когда названия методов и классов из строк собираются. Во всяких Yii и Laravel.
 

MiksIr

miksir@home:~$
Сервис - это не класс или интерфейс. Сервис - это конкретный объект. Инстанс.
Тип может не иметь сервисов, а может иметь несколько.
А у конкретного объекта (внезапно, ООП вообще имеет дело с конкретными объектами) может не быть типа (класса) или интерфейса, зато может быть какой-то сервис? Прикольненько.

Объясните мне о чем этот товарищ говорит, что за новое слово в программировании не на интерфейсах, а на сервисах?
 
Сверху