компонентный подход, мвс и шаблоны

Духовность™

Продвинутый новичок
А ведь в чём основная проблема?
У меня - в том, что ты описал: я не хочу иметь "код, специфичный для данной страницы, и только для неё". Меня дико раздражает факт того, что мои контроллеры имеют вид классов с методами по 200 строк! Эти 200 строк метода и являются теми самыми кусками кода, "специфичными для данной страницы". И это именно логика контроллера, все частые операции вынесены в соответствующие классы.

Вот пример метода, который занимается регистрацией пользователя: http://intercomp-global.com/temp.txt

Вот от такого нагромождения я и хочу избавиться, но куда уж дальше абстрагироваться- не знаю.
 

atv

Новичок
Но ведь ни кто не запрещает разбить эти 200 строк на несколько методов объединённых логически. Не важно, что эти методы больше не будут нигде использоваться, зато они позволят сделать алгоритм более наглядным.

Например первые строки имеют отношение к необходимой инициализации. Никаких локальных переменных в этих строках не создаётся, используются только свойства класса, вот и вынеси их в отдельный метод
PHP:
protected function init()
{
    $this->checkIsLoggined('/'.$this->request->_controller_alias.'/info/');

    $this->view->goHtmlTitle()->add( $this->view->lang->html_title );

    $this->session = Session::getInstance('captcha');
    $this->session->start();

    $this->view->session_name = $this->session->getName();
    $this->view->session_id = $this->session->getId();

    $User_Mapper = new User_Mapper();
    $this->user = $User_Mapper->createNew();

}
далее, у тебя стоит условие в котором очень много строк, и понимание самого условия затрудняется. Оставь условие в верхнем методе, а "внутренности" вынеси в отдельный метод с понятным названием, например:

PHP:
public function registration()
{
    $this->init() // тот метод который мы выделили выше
    
    if (Request::isPost())
    {
        $this->processRegistration();
    }

    $Country_Mapper = new Country_Mapper();
    $params = array
    (
        'what' => '`id_country`, `country_name_'.LANG.'` as `country_name`, `country_iso`',
        'order' => array('id_country' => 'ASC'),
    );
    $this->view->countries = $Country_Mapper->getObjectList($params)->getData()->getDataAsArray();

    $this->view->captcha_code = $this->request->captcha_code;
    $this->view->user = $this->user->getData();
 
}
Далее, уже в самом методе processRegistration() у нас происходит валидация и действия в случае успешной и не успешной валидации. Так и пиши:
PHP:
protected function processRegistration()
{
    if ($err = $this->validateForm())
    {
        $this->view->err = $err;
        //$this->view->user_phones = $user_phones->getData()->getDataAsArray();
    } else {
        $this->saveUserData();
    }
}
И т.д. По такому коду легко перемещаться и разбираться без дополнительного документирования.

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

Lightning

Трудоголик
triumvirat
1. Сделай чтобы контроллеры не знали о том, как взаимодействуют view и model.
2. Избавься от дублирования. (Выноси код, повторяющийся в разных контроллерах и моделях, в отдельные классы).
 

Духовность™

Продвинутый новичок
Никаких локальных переменных в этих строках не создаётся, используются только свойства класса, вот и вынеси их в отдельный метод
я как-то всегда сторонился этого. вероятно потому, что исходил из принципа в стиле `если код повторно не используется, его нет смысла разбивать на подпрограммы`


Спасибо за примеры. Попробую писать "покомпактнее" методы.

-~{}~ 26.06.09 15:50:

Lightning
Пример приведи. Что значит "не знали"?
 

atv

Новичок
Сделай чтобы контроллеры не знали о том, как взаимодействуют view и model.
Но кто-то же должен об этом знать.

Избавься от дублирования. (Выноси код, повторяющийся в разных контроллерах и моделях, в отдельные классы).
Он это делает - "все частые операции вынесены в соответствующие классы. "

Он не знает что делать со специфическим кодом отдельной страницы, которого накапливается достаточно много.
 

Lightning

Трудоголик
Но кто-то же должен об этом знать.
Об этом должен знать View (если модель полностью пассивная)
Или View и Model (Активная модель, паттерн Subscriber/Publisher)

-~{}~ 26.06.09 15:57:

и какой в этом смысл? плодить одноразовые классы?
Можешь не плодить. Тогда создавай через фабрики.
 

atv

Новичок
Кстати, ты читал у Фаулера про рефакторинг? Если нет, то почитай. Собственно, всё что я посоветовал, взято оттуда.
 

Lightning

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

atv

Новичок
Об этом должен знать View (если модель полностью пассивная)
Или View и Model (Активная модель, паттерн Sibscriber/Publisher)
А почему не контроллер? Я не вижу здесь однозначного критерия. Но из логики названия контроллера, самым активным должен быть он, а не модель и представление.

P.S. и так до опупения можно блудить в трёх соснах MVC :D

-~{}~ 26.06.09 15:05:

Но если дублирования нет, то код уже меньше не сделать.
Меньше нет. Его нужно структурировать, см. http://phpclub.ru/talk/showthread.php?postid=858900#post858900
 

Духовность™

Продвинутый новичок
Не знаю, все больше и больше считаю, что идеальная схема мвс это

PHP:
include('config.php');

// получение данных 

include('template.html');
Модель здесь - функции для работы с данными и базой.
Контролер - сама страница
Вид - шаблон на php strict
 

Lightning

Трудоголик
А почему не контроллер? Я не вижу здесь однозначного критерия.
Критерий - меньше кода.
Зачем передавать данные из модели в представление через контроллер? (вопрос риторический).
 

atv

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

P.S. бью себя по губам...
 

Духовность™

Продвинутый новичок
Lightning
Зачем передавать данные из модели в представление через контроллер?
Контролер он на то и контроллер, что бы обеспечить передачу данных от модели к представлению. Просто зачастую возникают ситуации, которые требуют логики непосредственно в контроллере. Ты предлагаешь под каждый пшик писать класс управления логикой для отдельно взятого контроллера отдельно взятого кода. Может это и правильно с точки зрения теории, но на практике это выльется в ужоснах.
 

Lightning

Трудоголик
Никого уговаривать не буду :)
Контролер он на то и контроллер, что бы обеспечить передачу данных от модели к представлению.
"Это Вас кто-то обманул" (с)
Ты предлагаешь под каждый пшик писать класс управления логикой для отдельно взятого контроллера отдельно взятого кода.
Нет, я такого не предлагаю.
Но ведь данные часто бывает нужно подготовить, причём специфическим образом для каждой страницы.
Например, как подготовить?
 

Духовность™

Продвинутый новичок
Например, как подготовить?
PHP:
$Country_Mapper = new Country_Mapper();
    $params = array
    (
        'what' => '`id_country`, `country_name_'.LANG.'` as `country_name`, `country_iso`',
        'order' => array('id_country' => 'ASC'),
    );
    $this->view->countries = $Country_Mapper->getObjectList($params)->getData()->getDataAsArray();
кто этим должен заниматься, если не контроллер?
 

Lightning

Трудоголик
Если просто подготовить к отображению, то этим хелперы всякие занимаются в шаблоне.
Вся остальная "подготовка" данных относиться к бизнес логике.

-~{}~ 26.06.09 16:59:

triumvirat
кто этим должен заниматься, если не контроллер?
Сначала скажи, зачем ты тут создаешь вообще какие-то объекты? Почему сразу не отдать данные массивом?
$Country_Mapper->getObjectList($params)->getData()->getDataAsArray()
поясни
 
Сверху