Как стать автором
Обновить

Комментарии 15

А зачем собственно нам нужно делать такие изменения? Есть ли какой нибудь пример из реальной жизни где такой вариант будет реально полезен? У вас действительно есть контроллер который используется в 2-х фреймворках одновременно?
В третьей части автор поясняет свою точку зрения на этот вопрос, скоро я эту часть допереведу, сможете там прочитать. А вообще, обобщая позицию автора, суть тут в том, что разработчик сам по себе начинает лучше замечать зависимости, и ему больше не кажутся «магией» аннотации и конвертеры параметров. Ну и плюс, контроллер-как-сервис очень проще для восприятия, чем ContainerAware-контроллер — все зависимости сразу видно; сразу, например, понятно, нужен ли контроллеру доступ к БД, и если нужен, то к каким репозиториям, и так далее.
Вообще в свое время ContainerAware контроллеры приходилось делать, это только с Symfony 2.3 DiC поддерживает ленивую инициализацию зависимостей (оборачивает их в прокси-объекты). Раньше же при инициализации контроллера инициировались и все все все сервисы, которые мы инджектили. Что бы этого избежать, приходилось инджектить контейнер целиком.
У меня был случай, когда в рамках рефакторинга проекта и его последующего переноса на другой фреймворк, пришлось вносить отдельный слой отделяющий компоненты фреймворка от приложения. В целом обычно это хорошая практика. Например отвязать контроллеры от Doctrine (инджектить отдельно репозитории и завязывать их на свои интерфейсы, не используя снаружи функционал Doctrine), что позволит быстро и безболезненно сменить хранилище данных. В последней части этой серии статей автор даже сам говорит, что отвязывать контроллеры и от HttpKernel это перебор, хотя раз уж начали то так будет правильно.
На самом деле, основные плюсы кроются не в том, что контроллер можно реюзать, а скорее, наоборот, тонкий клиент и связывание дает кунштюки:

— Можно заменить сервис, реализующий ту или иную плюшку (например, подменив EntityManager доктрины часть самых тяжелых методов перепишется на максимально быстрый нейтив)
— С инъекциями проще потом поверх нужных методов подцепить что-то еще. Например, логгер.
— Замена некоторых зависимостей полностью — не такой уж частый, но важный кейс в разработке хоть сколько-то дольше месяца,
— Наконец, позволяет тестировать сервисы модульно, в своих контекстах, так что контроллер, который тянет за собой все окружение, тестировать или не надо, или просто, или достаточно пары функциональных стандартных тестов.
Спасибо все ответы весьма неплохие. Возможно тогда стоит немного изменить название темы например: «Как уменьшить связность контроллера с фреймворком». Все ответы говорят о том что основная цель это не использование нескольких фреймворков с одним кодом, а именно уменьшение связности классов контроллеров. И в таком варианте это действительно имеет смысл. Правда я думаю что в таком случае подходить стоит без особого фанатизма например явная инъекция зависимостей это однозначно хорошо а вот отказываться от сахара аннотаций думаю нет большого смысла.
Ну, мопед не мой, а по футеру так и текст переводной.

Про аннотации — мне самому они очень нравятся, особенно в роли описания кеша/темплейтов/и т.п., но порой действительно вынос роутингов в дерево yaml дает большую гибкость, особенно в больших проектах. По крайней мере, ищется нужный даже в большой команде легко, роуты видно в одном месте (и на одном экране, что важно),

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

Хотя, когда писали самодокументируемый REST-сервис с помощью NelmioApiDocBundle, многое было на аннотациях и было очень вкусно и красиво, даже описание парамтетров, передаваемых в query, и принимаемых в POST сущностей.
роуты видно в одном месте (и на одном экране, что важно)


Вы все еще в ручную глазами в конфигах ищите соответствия роутов экшенам?

php app/console router:debug в связке с grep будте в любом случаее удобней.

В PhpStorm можно просто по названию роута сразу в нужный экшен попасть:

image
Ну, это про поиск и навигацию по аннотированным @Route экшенам. А если вы вдруг, например, захотите во всех экшенах суффикс _list заменить на _index, например? Или, например, для всех рутов с суффиксом _new ограничить методы только POST'ом?
Имхо, куда удобнее будет сделать изменения в одном или нескольких routing.yml и получить красивый и аккуратный коммит, по changeset'у которого явно видно, что он касается только роутинга, нежели получить изменения в большинстве, а то и во всех контроллерах.
Кстати, это еще один аргумент за конфиги и против аннотаций.
Согласен, но вы описали редкую задачу. Для меня удобство видеть с кодом экшена и его роут, поддерживаемые http-методы, шаблоны и т. д. перевешивает недостатки.

С хранением роутов в одном файл сталкивался в rails. Для больших проектов это выглядит довольно дико.
kix привел более важный довод нежели удобство поиска или редактирования — история изменения проекта выглядит более лаконично. Посмотрите хотя бы историю изменений приведенного вами конфига Redmine, все локонично, видно все изменения косательно раутинга…
Но ведь вам никто не мешает разносить роутинг по бандлам! Более того, это даже рекомендуемый путь для Symfony2-приложений. При генерации бандла конфигурация роутинга для него не конкатится к app/config/routing.yml, а инклудится в нем:

ck_finder:
    resource: "@JonlilCKFinderBundle/Resources/config/routing/routing.yml"
    prefix: /cms/ckfinder

И что еще важнее, вы вполне можете объявить несколько конфигураций роутинга в рамках одного бандла, либо точно так же инклудить другие конфиги при помощи resource.
Получается, что в пути src/My/AcmeBundle/resources/config могут быть, например, сразу routing_front.yml и routing_admin.yml, импортируемые в app/config/routing:

acme_front:
  resource: '@MyAcmeBundle/Resources/config/routing_front.yml'
  prefix: /

acme_admin:
  resource: '@MyAcmeBundle/Resources/config/routing_admin.yml'
  prefix: /admin/
Все что описывается в статье не имеет никакого отношения к небольшим проектам и быстрой разработке. То есть обычно на таких проектах и так не пользуются аннотациями или хотя бы стараются не использовать их. Если уж выбран один формат хранения конфигов — стараются придерживаться именно его. В зависимости от проекта можно перенимать лишь часть практик.
А тут как в жизни — когда говорим об энтерпрайзе, задумываемся об архитектуре, масштабируемости и всем таком. Когда говорим о небольших проектах, речь идет только о том, как построить сам процесс разработки максимально быстро. Остальное имеет стремящееся к нулю значение.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории