Разделение уровней и ООП

mars37

Новичок
Разделение уровней и ООП

Люди! Поделитесь опытом, мыслями, соображениями вот по какой теме...

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

Очень удобно в классах инкапсулировать полную функциональность некоторой сущности. Например класс TUser. В нём удобно реализовать:
1. методы добавления, изменения, удаления записей о пользователе (уровень содержимого)
2. методы выборки например статистических данных о пользователе, методы отсылки сообщений пользователю (уровень логики)
3. методы формирующие формы для ввода данных о пользователе, методы представления данных о пользователе (уровень представления)

При таком подходе получается, что в объекте TUser "смешались" все три уровня, что не очень-то согласуется с идеологией разделения уровней.

Вопрос: как "примерить" идеологию разделения уровней в проектах и идеологию инкапсуляции поведения объекта?
 

master_x

Pitavale XXI wieku
mars37
1. методы добавления, изменения, удаления записей о пользователе (уровень содержимого)
это у нас контроллер а не модель, никакого уровня содержимого здесь нет.
2. методы выборки например статистических данных о пользователе, методы отсылки сообщений пользователю (уровень логики)
статистика по пользователю может пойти в модель а вот отсылка почты идет в контроллер (смотри выше).
3. методы формирующие формы для ввода данных о пользователе, методы представления данных о пользователе (уровень представления)
тут либо использовать обыкновенные шаблоны, формы... либо опять же вызывать методы отрисовки форм в контроллере.
 

whirlwind

TDD infected, paranoid
2 и 3 каким боком тут? А если юзера придется в космос запускать к этому же классу будеш дописывать физику полета ракеты?

2й сделай мейл тулкитом - отдельный класс, который на основе объектов бизнес логики будет письма рассылать.
3 - это вообще отдельная песня. Изменение вида никак не связано с изменением атрибутов пользователя.
 

chulim

Новичок
mars37
вам читать теорию про mvc нужно, много и вдумчиво.
и не мешать в один объект модели, хелперы и контроллеры
 

Фанат

oncle terrible
Команда форума
Классические ответы в стиле пхпклаба.
Три сообщения с объяснениями, что у человека плохо.
Ни одного - с предложениями, как сделать хорошо.

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

mars37

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

это у нас контроллер а не модель, никакого уровня содержимого здесь нет.
А вот в книге "Профессиональное PHP программирование", 2-е издание (ISBN 5-93286-049-9), стр. 584 именно такие методы относят к уровню содержимого.
Может Вы имеете ввиду нечто другое чем я? Я например вообще слово "модель" не писал...

А если юзера придется в космос запускать к этому же классу будеш дописывать физику полета ракеты?
Нет, физика полёта будет реализована в классе TRaketa, а в класс TUser я добавлю метод SendToSpace, в качестве параметра метода скорее всего укажу переменную типа TRaketa, или даже более общего типа TTransport :)

2й сделай мейл тулкитом - отдельный класс, который на основе объектов бизнес логики будет письма рассылать
Да это просто привёл для примера. Естественно я не буду в классе TUser реализовывать отсылку почты. В этом методе "отсылки" можно например формировать текст письма, учитывающий ФИО пользователя, его пристрастия, особенности, возраст, знак зодиака наконец. А потом, после формирования текста вызывается метод другого класса, реализующий саму физическую отправку... Давайте обсуждать идеологию, а не способы решения частных под-проблем, хорошо?

3 - это вообще отдельная песня. Изменение вида никак не связано с изменением атрибутов пользователя.
А кто писал про изменение вида? Здесь могут быть например такие методы как
"Сформировать html-код формы редактирования свойств пользователя"
"Сформировать html-код, представляющий свойства пользователя"
"Сформировать wml-код, представляющий свойства пользователя"
"Сформировать html-код, представляющий статистику по пользователю"
Скажете это никак не связано с атрибутами пользователя???

вам читать теорию про mvc нужно, много и вдумчиво.
и не мешать в один объект модели, хелперы и контроллеры
Согласен. Иначе бы не писал сюда ;-) Можете порекомендовать on-line источники?
 

С.

Продвинутый новичок
Все помешались на MVC, хотя еще не понятно, где там граница между слоями (пример с выдачей дерева). Как и совсем не однозначно, что работа с базой данных пользователей обязанность контролера

Нормальный вопрос человек поднял. Наряду с "горизонтальным" делением (MVC) можно рассматривать и "вертикальное", которое тоже дает определенные дивиденты. Как только их скомбинировать?

На мой взгляд, во-первых, надо абстрагироваться от ООП терминологии. Объект работы с пользователем может не быть объектом per se, a скажем набором объктов, объедененных в модуль. В модуле может быть два слоя (M и V). Отсюда логично исключение модуля из контролера. Таким образом мы получаем "легкий" контролер и набор системных модулей к нему. Причем получается, что при необходимости мы можем вызывать только M-компоненту модуля, когда нужно сделать какую-нибудь операцию "в фоне". Для работы в GUI соответственно подключаются обе компоненты.
 

whirlwind

TDD infected, paranoid
а в класс TUser я добавлю метод SendToSpace, в качестве параметра метода скорее всего укажу переменную типа TRaketa, или даже более общего типа TTransport
Вот, правильно. А еще правильнее

PHP:
$raketa->SendToSpace($user)
это у нас контроллер а не модель, никакого уровня содержимого здесь нет.
По этому вопросу я тоже с камрадами здесь спорю. ИМХО контроллер - это адаптор между моделью (или несколькими элементами модели) и конкретным представлением, но никак ни бизнес-логика.
 

mars37

Новичок
Ага... вон оно что! В первоначальных ответах опирались на паттерн mvc, используя его терминологию. Но я про него совсем не думал...
 

BeGe

Вождь Апачей, блин (c)
С. А в чём проблема отрисовки Дерева ?

Дерево это только представления связного списка (если вы не знаете что это такое, то думаю вам ещё и до MVC далеко).

Некоторые объекты иногда посто проще выводить уже в HTML. То есть во view ты уже передаёшь готовый "выход" объекта. Такой типа объекта лучше назвать Widget.

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

Класс модели - Order, Shopingcart, Grapth.... у них основной метод getData.

Дальше Контроллер вызывает объект Представления - который уже знает, как и что рисовать. Контроллер вообще не знает что за данные были переданы Представлению.

Представление уже решает будет ли это бинарный output или это будет html страница.
 

StUV

Rotaredom
whirlwind
контроллер - это адаптор между моделью (или несколькими элементами модели) и конкретным представлением, но никак ни бизнес-логика
а чем занимается контроллер/адаптор ?
и где бизнес-логика ?

-~{}~ 16.12.06 17:40:

Дерево это только представления связного списка
неужели ? =)
 

master_x

Pitavale XXI wieku
whirlwind
По этому вопросу я тоже с камрадами здесь спорю. ИМХО контроллер - это адаптор между моделью (или несколькими элементами модели) и конкретным представлением, но никак ни бизнес-логика.
ну естественно это только имхо. то, что я скажу не есть истина в последней инстанции, но по-хорошему контроллер-- он никакой не адаптер между моделью и представлением. если конкретнее, то модель может предоставлять интерфейс для доступа к данным, а представление может напрямую пользоваться этим интерфейсом (безо всяких адаптеров). но это уж как вам удобнее. контроллер-- это некий объект который изменяет данные (управляет ими).

-~{}~ 16.12.06 17:43:

mars37
Да это просто привёл для примера. Естественно я не буду в классе TUser реализовывать отсылку почты. В этом методе "отсылки" можно например формировать текст письма, учитывающий ФИО пользователя, его пристрастия, особенности, возраст, знак зодиака наконец. А потом, после формирования текста вызывается метод другого класса, реализующий саму физическую отправку... Давайте обсуждать идеологию, а не способы решения частных под-проблем, хорошо?
ну ты крут, привел тут задачу, с конкретными проблемами и вопросами, а теперь идеологию обсуждать решил...
 

whirlwind

TDD infected, paranoid
StUV ну мы же уже обсуждали этот вопрос и вроде решили остаться каждый при своем мнении ;)

Модель - это модель, а не просто table gateway. Модель двигателя подразумевает что внутри _работают_ (механизм) цилиндры, а не только то, что целиндры существуют и имеют какой-то объем (атрибуты).

Контроллер работает с драйвером ввода-вывода и транслирует команды пользователя в модель, т.е. пользователь инициирует какие-то процессы, уже реализованные в модели. В контроллере определяется что вот конкретно эта кнопка вызывает метод save модели, а вот эта кнопка позволяет получить текущий баланс, вот это поле указывает новое значение вот такого-то атрибута вот такого-то элемента модели и проч. Т.к. веб приложения не интерактивные, то на контроллер я так же возлагаю обратную связь модель->представление.
 

StUV

Rotaredom
whirlwind
=)
да это я так риторически... вырвалось - чтобы другие поняли о чем это ты ;)
 

whirlwind

TDD infected, paranoid
то модель может предоставлять интерфейс для доступа к данным, а представление может напрямую пользоваться этим интерфейсом (безо всяких адаптеров)
Никакой объект модели вам не представит возможности получить аналитический срез, потому что сам объект не может знат про себя - в каких контекстах он используется. Так более понятен смысл контроллера-адаптора?
 

master_x

Pitavale XXI wieku
whirlwind
т.е. в вашем случае контекст модели определяется контроллером?
 

whirlwind

TDD infected, paranoid
Да. Вот простые примеры выборки вдвух разных контроллерах. Класс модели один и тот же


Контроллер списка бандлов
PHP:
    function stageSelect(){
        $bundle = $this->getBaseController()->getObject();
        $bundle->filterBy("f_bundle",true);
        $bundle->orderBy("name");
        $bundle->selectObjects();
        return true;
    }
Контроллер списка продуктов
PHP:
    public function stageSelect(){
        $obj = $this->getBaseController()->getPersistentObject();
        $obj->resetFilter();
		$selected_order = $this->order_by->listGetIdSelected();
		$selected_order_desc = $this->order_desc->getValue();
		$limit = $this->limit->listGetIdSelected();
		if ( $limit != "all" && is_numeric($limit) ) $obj->setLimit($limit);
		$obj->orderBy($selected_order,$selected_order_desc);
		$obj->filterBy("f_package",false);
        return $obj->selectObjects();
    }
Более сложные примеры, где в зависимости от контекста используются различные совокупности классов модели смотрите здесь http://phpclub.ru/talk/showthread.php?s=&threadid=91066&rand=195
 

master_x

Pitavale XXI wieku
whirlwind
может мой способ извращенный, спорить не буду, но у меня контекст определяется в другом месте =) поэтому модель и контроллер модели у меня могут существовать друг без друга хоть и в ущербной форме.
 

whirlwind

TDD infected, paranoid
master_x дык я все понимаю, своя рубашка и тп ... :)

Просто интересно, а как вы называете (классифицируете) то "другое место"? Если хелперы+активные шаблоны, то в принципе понятно.
 

master_x

Pitavale XXI wieku
whirlwind
другое место у меня называется фронт-контроллером (чувствую огромный пинок под зад)... если интересно расскажу как это все работает, но лучше бы либо в личку либо в отдельной теме...
 
Сверху