Допустим, есть web-сайт, написанный на каком-либо языке программирования, использующий паттерн MVC. Все формы на сайте представлены объектами, публичными свойствами которых являются элементы формы, а методы позволяют произвести проверку формы на факт отправки, валидацию и т.д. Данные формы извлекаются из свойств, которые реализуют также рендеринг контролов, собственную валидацию, изменение состояния.
Вопрос концептуальный и состоит в том, где должна в этом случае располагаться логика приложения, например сохранение данных из формы в базу, – в контроллере или в самой форме, например как реализация метода onPostAndValidate, onValidateError(), etc. В случае обработки формы из контроллера возникает копирование логики обработки POST запроса для каждой формы. Если все инкапсулировать в форму, то возникает смутное сомнение в смешивании ответственности – не окажется ли перегруженым класс формы. Вот такая делема. Как посоветуете сделать?
А вы добавте сюда ещё случай когда нужно добавить правило валидации типа «уникальныный емэйл в базе», или с течением времени вы решили изменить столбец в таблице БД и теперь сохранять длинну поля не 100 а скажем 200 символов — получится совсем путаница. Другими словами валидация формы в общем случае так или иначе тесно переплетается с моделью.
Можно попробовать сделать так:
Вся валидация должна происходить в моделе при сохранении. Модель при сохранении возвращает «объект овета» в котором содержится результат работы: перечислены ошибки валидации, какието вспомогательные данные (сколько строк было сохранено или обнавлено), при удачном сохранении также объект сущности которую сохраняем.
В контроллере проиходит связывание и согласовывание объекта формы и «объекта ответа»
Проблема в том, что форма тоже должна знать правила валидации. Хотя бы для того, чтобы рассказать об этом JS специальными атрибутами контролов или сгенерированными функциями валидации. Или нужно каким-то образом извлекать формализованные правила валидации из модели и генерировать соответствующий клиентский код.
Еще одной проблемой является отличие правил валидации формы от правил валидации модели. То есть вовсе не всегда по ответу модели можно понять, в каком контроле были неправильно введены данные. Не обязательно взаимное соответствие структуры модели и полей формы. Хотя в большинстве случаев так оно и есть.
То есть должны быть 2 валидации — в форме и модели. И вот опять дублирование функциональности — изменили правило валидации в модели, а затем во всех формах, которые используют эту модель. Хотя к этому можно относиться с пониманием — одно дело UI, а другое данные.
Возможно, вам стоит создать отдельные классы-Entity, которыми и манипулировать на всех слоях приложения.
M, V и C — это «подслои» UI. А кроме UI часто выделяют отдельные слои бизнес-логики (BLL) и доступа к данным (DAL). Таким образом, в своем MVC вы можете манипулировать данными, а затем передавать их в виде Entity-объектов в классы бизнес-логики, которая, в свою очередь, будет вызывать методы доступа данных для CRUD-операций.
Это всего лишь один из вариантов архитектуры. Все зависит от конкретного приложения, но подробности у вас бы вряд ли уместились в вопрос, так что… думайте, выбирайте :) Или же задавайте более конкретные вопросы.
Вопрос в том, откуда вызывать операции по управлению бизнес логикой — из формы или контроллера? Где заполнять Entity-объект из формы — в самой форме или в контроллере?
Я так понимаю, что у вас не MVC в чистом виде, так как присутствуют классы-формы со своим поведением.
Как я понимаю MVC: есть View, в котором задается чисто отображение/layout.
Есть Model — это контейнер данных, который подсовывается View'шке. В каком-то смысле, это аналог паттерна DTO.
И есть контроллер, который осуществляет роутинг: какое действие выполнить, куда перенаправить запрос, и т.п. И контроллер, как раз, и формирует Model'и, которые подаёт во View.
Методы бизнес-логики должны вызываться как раз из контроллера. Больше, собственно, неоткуда.
То же самое с заполнением Entity-объектов.
А вот какую конкретно функцию у вас выполняют классы-формы, и почему вы думаете, что это вписывается в концепцию MVC, — непонятно :)
Форма должна инкапсулировать в себе извлечение данных из HTTP запроса, рендеринг контролов и валидацию данных на стороне формы. В контроллере обычен такой код:
SomeForm form = new SomeForm();
if(form->wasSent())
{
if(form->validate()
{
BusinessLogic.saveEntity(form->field->getValue());
System.redirect('/confirm');
}
}
//render page with form
Если вынести все проверки на отправку форму и валидацию в базовый класс формы, то останется всего лишь переопределить соответсвующий метод формы (onPostAndValidate). Контроллер упростится
SomeForm form = new SomeForm();
form->processRequest();
//render page with form
Нужно посмотреть, что конкретно делается — смотрите подробнее форму. Да, теряется гибкость в логике обработки формы, зато упрощаются контроллеры. А форма скорее всего приобретает ненужную ответственность за вызов обработчика данных.
Попробуйте выделить отдельный класс, который будет отвечать за данные, которые нужно послать в БД или вытащить из нее, а при сохранении в БД в контроллере запрашивайте этот класс из формы и отдавайте его на растерзание классу БД (или терзайте прямо там).
Форма как элемент UI не должна знать про БД, но должна отдавать данные в каком-то виде. Контроллер как прослойка между UI и DB должен превращать данные из UI в данные, пригодные для DB.