Компонент формы Symfony2 - нарушение MVC и SRP?

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

Я наткнулся на эту статью здесь и я нахожу, что согласен с автором. Даже если статья посвящена Symfony 1.x, я думаю, что она по-прежнему актуальна для компонента Form в Symfony2. На самом деле кажется, что компонент формы пытается решить проблемы, связанные с шаблоном, контроллером и моделью, в одном месте. Разве это не нарушает MVC и/или SRP (принцип единой ответственности)?

Это может быть другой вопрос, но я чувствую, что это как-то связано — я также заметил, что многие доступные пакеты для symfony пытаются решить проблемы с представлением вне представления, например:

KnpMenuBundle - вы создаете меню на стороне сервера с oo-интерфейсом (почему не в слое представления, где они принадлежат?)

IvoryCKEditorBundle - преобразование textarea в ckeditor выполняется в одной строке jquery в файле представления, так почему этот пакет существует? Я даже не хочу считать количество строк там.

Получается, что везде в ядре Symfony есть эти нарушения, или я просто не понимаю?


comment
Это сторонние инструменты. Несмотря на то, что в Sf2 есть конструктивные недостатки, нарушение SRP в реальном ядре фреймворка минимально и применяется только тогда, когда это прагматичное решение. То, на что вы смотрите, не является ядром.   -  person tereško    schedule 02.04.2013
comment
Я имел в виду, что где-то в основной идее Symfony существует что-то, что заставляет людей писать эти сумасшедшие пакеты. Но разве компонент формы не является основным компонентом фреймворка?   -  person moljac024    schedule 02.04.2013
comment
В Zend Framework такие компоненты есть, но это совсем ужас. Я пришел к выводу, что создание каких-либо универсальных конструкторов форм — совершенно бесполезное занятие.   -  person tereško    schedule 02.04.2013
comment
Вы бы сгенерировали клиентскую часть своего меню? Пожалуйста, выберите слова. Разделение задач поддерживается в KnpMenu, генерация разметки делегируется уровню представления, а иерархия меню делегируется определенному классу. В чем проблема ? Я отвечу вам: использовать его для создания простого меню из 3 пунктов :)   -  person Florian Klein    schedule 19.04.2013


Ответы (1)


Проблема с обработкой форм заключается в том, что она по определению нарушает MVC. Это проблема, известная как «сквозное пересечение», и в прошлом она изучалась наукой. Документ Веб-разработка на основе домена с помощью WebJinn, например, интересно почитать по теме.

В качестве примера подумайте об отношении форм к различным уровням MVC:

Модель:

  • Формы копируют информационную структуру вашей модели предметной области (DM). Если вы изменяете эту структуру (например, добавляя поля в структуру данных или добавляя параметры в процедуру), вы также должны адаптировать формы для ввода этой информации.
  • Им нужна информация о типе от вашего DM, чтобы преобразовать входные данные в требуемые там типы.
  • Им необходимо знать ограничения, указанные в вашем DM, чтобы подтвердить ввод.
  • В идеале они считывают и записывают данные непосредственно из/в ваш DM (например, читая/записывая поля структуры данных или вызывая процедуру в DM с отправленными значениями в качестве параметров).

Контроллер:

  • Формы получают отправленные данные и отправляют их в DM.
  • Они изменяют ход программы в зависимости от того, успешно они проходят проверку или нет.

Просмотр:

  • Формы отображаются как сложная структура HTML-тегов и атрибутов, которая зависит от всего вышеперечисленного (должно ли поле быть обязательным? должны ли отображаться ошибки? как упорядочить поля? какие варианты выбрать в раскрывающемся списке? и т. д.)

Следовательно, невозможно написать механизм абстракции формы, который не затрагивал бы все эти уровни. Решение, наоборот, состоит в том, чтобы структурировать саму библиотеку форм в соответствии с MVC, на разные уровни и подкомпоненты, которые выполняют SRP. Если вы посмотрите на компонент формы Symfony2, он делает это очень хорошо. ;)

Так почему же это такой «огромный страшный зверь»? Первая проблема связана с абстракцией. Например, подумайте о простом раскрывающемся списке. Если мы хотим повторно использовать код раскрывающегося списка, нам нужно как-то его абстрагировать. Теперь проверьте список выше, даже этот простой ввод затрагивает все три уровня приложения MVC. Как можно абстрагироваться от чего-то, что должно быть разделено на три разные части?

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

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

Вы видите, что библиотеки форм оказываются довольно сложными. Лучшее, что мы можем сделать при написании таких «огромных страшных зверей», — сделать их API как можно более простым для начинающих, максимально гибким для более продвинутых пользователей и написать обширную документацию по использованию его полной мощности. Последний пункт определенно все еще отсутствует (пожалуйста, помогите!), но мы постоянно работаем на все вышеперечисленное.

Свести сложную задачу к простой, к сожалению, невозможно.

А как насчет других библиотек форм, которые намного проще? По моему скромному мнению, они даже не пытаются решить большинство проблем, которые компонент Symfony2 Form уже решает за вас. :)

Обновление от 24 января 2014 г. Для всех, кто хочет узнать больше (намного больше), вот документ, который я опубликовал на эту тему.

person Bernhard Schussek    schedule 19.04.2013
comment
Не могли бы вы уточнить, что вы считаете моделью предметной области? Во всяком случае, компонент форм Symfony стимулирует анемичные модели... - person Marijn Huizendveld; 19.04.2013
comment
Поясню, о чем я прошу. Например, вы говорите: Формы повторяют структуру вашей модели предметной области (DM). Я не могу не согласиться с вами более решительно. Они должны позволять вам изменять модель предметной области, выполняя методы, представляющие поведение. Помещение модели предметной области в формы — одна из худших предпосылок, на которых построен компонент формы. - person Marijn Huizendveld; 19.04.2013
comment
Я имел в виду информационную структуру. Если ваша доменная модель моделирует сотрудников и у вас есть формы для изменения данных этих сотрудников, вам, скорее всего, придется адаптировать формы, если информационная структура вашей доменной модели изменится (например, вы удалите дату рождения, но вместо этого добавите номер социального страхования). - person Bernhard Schussek; 19.04.2013
comment
Я говорю, что Symfony ошибается, когда просит меня внедрить мою модель предметной области в форму. Когда пользователь отправляет форму, он в основном сообщает приложению: выполните операцию n с данными x, y и z. Для этого мне не нужно вводить мою доменную модель в форму. Это освобождает мою модель от необходимости показывать ее состояние, что значительно облегчает работу. Однако компонент формы symfony просит меня сделать это с геттерами и сеттерами, оставляя большинство пользователей с анемичной моделью. Это похоже на реальную сделку, но это просто модель данных, ни больше, ни меньше, без какой-либо ценности. - person Marijn Huizendveld; 19.04.2013
comment
Вы правы в том, что отправка формы эквивалентна выполнению операции n с данными x, y и z. Но n также является частью вашего DM. Если вы измените его подпись (например, удалите z), вы также измените информационную структуру DM. Теперь передача ваших объектов данных на уровень формы является опцией в Symfony для ускорения кодирования при определенных обстоятельствах — то есть, когда n соответствует записи x, y и z в этот объект — но это ни в коем случае не обязательно. - person Bernhard Schussek; 19.04.2013
comment
Я адаптировал модельную часть своего ответа, чтобы прояснить это. - person Bernhard Schussek; 19.04.2013
comment
Я говорю, что Symfony ошибается, когда просит меня внедрить мою модель домена в форму, которая вам не нужна, формы могут иметь свои собственные модели, тогда вы можете передать модель формы в службу, которая будет использовать эту модель. и модели домена.Возьмите регистрационную форму, у вас может быть модель регистрации для RegisterType и модель пользователя, не используемая в контроллере. это то, чем я занимаюсь. symfony ничего не навязывает. мои контроллеры ничего не знают о моделях домена, мои службы знают. - person mpm; 22.04.2013
comment
Очень красивое изложение. Теперь я лучше понимаю сложные проблемы, которые пытается решить компонент формы. - person moljac024; 24.07.2013