ТТУК - Толстые тупые уродливые контроллеры

fixxxer

К.О.
Партнер клуба
дык я не типовые прямо так и создаю щас в контроллере, с явно указанными валидаторами. но тогда приходится городить дополительную логику, типа
PHP:
if (!$Profile->validate()) {
    $Form->Errors->fetchFrom($Profile->getErrors())
} else {
    $Profile->save();
}
ну и дублирование полей мне не нравится
 

Fortop

Новичок
дык я не типовые прямо так и создаю щас в контроллере
Не, ну смысл это делать в контроллере?

Я имел в виду, что то, вроде такого
PHP:
class My_Form extends Form {
    public function build()
    {
        // инициализация элементов, валидаторов и т.д.
        $this->addValidate(чего-нибудь);
    }

    public function isValid($data)
    {
        $actualData = array_intersect_key($data, $this->elements);
        $errors = array();
        foreach($this->elements as $id => $element) {
            $value = (isset($actualData[$id]) ? $actualData[$id] : null);
            $errors += $element->validate($value)->getErrors();
        }
        $errors += $this->model->validate($actualData)->getErrors();
        $this->_errors = $errors;
        return ($errors ? false: true);
    }
}
ну и дублирование полей мне не нравится
В смысле?
 

Духовность™

Продвинутый новичок
На самом деле, надо вынести свой валидатор, например, из метода post() в форму, сервисный слой или просто в Module_User_Mapper_User. И контроллер похудеет сразу на 40 строк
Если говорить конкретно об этом куске кода http://paste.org/pastebin/view/18126 то
В чём смысл переносить кусок кода из одного контроллера, в сервис, который, по-сути, является всё тем же контроллером ?
Ведь если я перенесу конкретно данную валидацию, что представлена по ссылке в коде, то она, эта логика, не будет использоваться НИГДЕ БОЛЬШЕ, КРОМЕ ЭТОГО КОНТРОЛЛЕРА! Я не вижу смысла делать ещё один слой.
 

zerkms

TDD infected
Команда форума
triumvirat
У тебя и вьюшек 90% используются только одним контроллером. Это не является поводом, чтобы валить их в кучу тогда.

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

HraKK

Мудак
Команда форума
Да ну, не вижу ничего плохого в валидаторах и фильтрах в контроллере.
Например та же регистрация, на каждый сайт она разная и это должен делать контроллер а не сервисный слой.
 

Духовность™

Продвинутый новичок
HraKK
Да ну, не вижу ничего плохого в валидаторах и фильтрах в контроллере.
Например та же регистрация, на каждый сайт она разная и это должен делать контроллер а не сервисный слой.
а чем должен заниматься тогда сервисный слой?
 

Beavis

Banned
Автор оригинала: zerkms
Я сейчас пришёл к варианту, когда к рядовым слоям MVC добавляется ещё один - сервисный слой (по факту там всё сложнее, но в общем виде именно так). Вот сервисный слой и содержит всю бизнес-логику.
о, я тоже до этого практически дошел)
а то получается что модели (например объекты ORM) мало чего умеют, и всю логику манипуляции ими приходилось писать в контроллере...

а про эти "сервисы" - есть какое-нибудь стандартное решение, паттерны, и т.п?
 

HraKK

Мудак
Команда форума
Всем что не включает в себя разбор внешних данных и отображением.

-~{}~ 05.05.10 11:43:

а про эти "сервисы" - есть какое-нибудь стандартное решение, паттерны, и т.п?
ага, The brain design pattern
 

Духовность™

Продвинутый новичок
Всем что не включает в себя разбор внешних данных и отображением.
Всё равно, я не понимаю.

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

zerkms

TDD infected
Команда форума
Всё, что не включает в себя разбор внешних данных и отображение - это бизнес-логика, присущая конкретному контроллеру.
вот именно, что нет :) это ты так привык.

Возьмем пример с регистрацией - вся логика, связанная с этим действием, а именно - валидация, сохранение и иные индивидуальные особенности этого действия уникальны в пределах проекта и больше нигде не используется.
а ты добавь теперь в проект openid + active directory ;-) и процесс создания юзера у тебя теперь продублируется дважды ещё :) В контроллере, который обрабатывает вход через openid, и через АД.
 

Mols

Новичок
Автор оригинала: HraKK
Да ну, не вижу ничего плохого в валидаторах и фильтрах в контроллере...
+1
До необходимости использования сервисного слоя я похоже не дорос.
Но почему-то мне кажется, что если контроллер будет реагировать на то, что будет возвращать сервисный слой(практически всегда уникальный для каждого контроллера) это мало похоже на увеличение гибкости. Придётся либо накладывать какие-то ограничения на то, что может возвратить сервисный слой в принципе и на этом строить их взаимодействие, либо контроллер будет вынужден "знать" о своей сервисном слое слишком много.

Автор оригинала: Beavis
о, я тоже до этого практически дошел)
а то получается что модели (например объекты ORM) мало чего умеют, и всю логику манипуляции ими приходилось писать в контроллере...
О !!! вот это подход. Нет нормальной модели - выносим кучу логики в контроллер. И вместо доработки модели хотим эту логику вынести в ещё один слой. Круто.
 

Fortop

Новичок
Какой смысл пихать ей в отдельный слой? Он нигде больше использоваться не будет.
Ну ты же не пишешь весь код лапшой.
А структурируешь его вынося отдельные логические части в классы/функции.

Вот и в данном случае такой же смысл - облегчить читаемость кода. В будущем, это кстати может помочь делать и подмену валидации и т.д.

-~{}~ 05.05.10 12:03:

Beavis
а то получается что модели (например объекты ORM) мало чего умеют, и всю логику манипуляции ими приходилось писать в контроллере...
Mols
О !!! вот это подход. Нет нормальной модели - выносим кучу логики в контроллер. И вместо доработки модели хотим эту логику вынести в ещё один слой. Круто.
Еще раз. Если логики немного - то она может находиться в контроллерах.
Но как только начинается вот такой движняк
zerkms
а ты добавь теперь в проект openid + active directory
руки сами потянутся убрать логику из контроллера в модели.

Следующий этап - когда логики в модели становится дохрена и она начинает путаться с логикой DBAL

тогда модель режется на 2-3 части.
Сервисный слой, дата маппер (и транспортная структура - может быть обычный массив или класс только со свойствами)
 

Духовность™

Продвинутый новичок
Ну ты же не пишешь весь код лапшой.
А структурируешь его вынося отдельные логические части в классы/функции.
для повторного использования прежде всего.

такой же смысл - облегчить читаемость кода
мне казалось, смысл слоя сервисов - повторно использовать логику, не? Ибо "читаемость кода" - вещь сугубо абстрактная. Для одних код в 50 строк уже не читабелен, другие вот так пишут и ничего.
 

Beavis

Banned
Автор оригинала: Mols
О !!! вот это подход. Нет нормальной модели - выносим кучу логики в контроллер. И вместо доработки модели хотим эту логику вынести в ещё один слой. Круто.
у меня под моделями в основном понимаются объекты ORM, которых на странице может быть не один десяток..
и где по твоему я должен вызывать загрузку этих моделек, их обработку и всякие прочие действия?

вот если всё это делать в контроллере, он раздувается сильно...
 

zerkms

TDD infected
Команда форума
и транспортная структура - может быть обычный массив или класс только со свойствами
хехе, я в самом начале угу ещё сказал, что всё в жизни сложнее.

у меня в текущем проекте на работе иерархия такая:

- контроллер работает с сервисом
- сервис работает с репозиторием (репозиторий - это класс, который умеет извлекать данные, согласно всяких хитрых условий. причём он оперирует только условиями, о самом персистентном хранилище он не знает ничего)
- репозиторий работает с датаконтекстом (датаконтекст - у меня это datacontext из linq2sql, т.е. класс, который умеет сохранять данные непосредственно в хранилище, и извлекать согласно правилам, которые задали)

и сущности:
- linq2sql entities (сами сущности linq2sql, на которые отображаются записи БД)
- domain model entity (это сущность в терминах бизнес-логики)

Контроллеры/Сервис/Вьюшки оперируют DM Entity.
Репозиторий - знает о тех и других. При операциях извлечения конвертирует l2s E в DM Entity , при операциях модификации - наоборот.
Датаконтекст - работает только с l2s Entity.
 

Mols

Новичок
Автор оригинала: Fortop
тогда модель режется на 2-3 части.
Вот. Моделей можно сделать больше. Но при чём тут сервисный слой?
Лично мне не понятны преимущества.
Для себя я всегда ищу баланс между гибкостью, универсальностью и простотой.
И на сегодняшний день даже мыслей о каком-то сервисном слое не возникало.
Это моё мнение по этому вопросу(опять же не претендующее на истину в последней инстанции)
З.Ы.
Ссылка в первом посте топика только у меня не работает?
 

Fortop

Новичок
маппер, если я правильно понял.

нижний уровень DBAL

Фиг его знает, что это из себя представляет. Я с C# и LINQ не очень. Возможно ближе к транспортной структуре.
тоже транспорт


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

-~{}~ 05.05.10 12:23:

Mols
И на сегодняшний день даже мыслей о каком-то сервисном слое не возникало.
А он часто-густо и не нужен. Я лишь в 2х задачах приблизился к нему и обе были ERP-класса.
 

Mols

Новичок
zerkms
Если не устраивает (по каким-то мифическим причинам) CUser->add($params)
Наследуем СUserActiveDir и переопределяем ->add($params).
Собсно всё.

В общем я ж говорю. Может я не дорос ещё. Хотя скорее всего у нас у всех несколько разные реализации, которые имеют разные особенности. Поэтому развивать спор смысла не вижу.
 

AmdY

Пью пиво
Команда форума
у меня было как-то так http://paste.org/pastebin/view/18148

-~{}~ 05.05.10 15:39:

рй, как вы далеко ушли, а я тормознул на первой стрнице. всё же температура даёт знать :(
 
Сверху