YiiFramework Yii PHP framework 2 public preview

fixxxer

К.О.
Партнер клуба
Ну, паттерны это не священная корова, а просто коллекция практик. Если получается сделать лучше отойдя от них, почему нет?

Правда я сомневаюсь, что "статика между классами" и "лучше" это совместимые вещи, но повторюсь, код не смотрел
 

fixxxer

К.О.
Партнер клуба
В Yii модель в статическом методе создает AQ, и отдает ее, и дальше уже мы все методы включая итоговый find вызываем у AQ, а тот уже возвращает модели. Так как AQ создана статикой - у нее нет объекта AR. Благодаря этому и со скоупами фигня - они вроде как должны быть в AR, как часть бизнес-логики, а вызываются у AQ.
А, ясно. Тогда я тоже не понимаю, почему не наследование/трейты.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
MiksIr, основное отличие в том, что AR представляет API для операции с одной записью,
а Yii предоставляет инструмент для работы с множеством - и тут начинаются пляски с бубном: коллекции на PHP толком не реализуются (array_функции их не принимают, без SplBool null-object нереализуем, и в дефолтной сборке недоступен), массивы в объектную модель не вписываются, хотим универсальный инструмент и для множества, и для одной записи, и чтобы работало побыстрее
 

MiksIr

miksir@home:~$
Я вот просто буквально на днях пересмотрел "корп. приложения" касательно работы с базой, и там Фаулер когда про AR пишет - включает туда же статические методы поиска. Утверждая, что выделение этого поиска в отдельных класс (как в случае с RDG) не особо и нужно.
 

Redjik

Джедай-мастер
Я вот тут посмотрел AR. А можете пояснить на пальцах, в чем плюсы разделения AR на AR+AQuery? Вот минусы с точки зрения использования - вижу, это и проблемы с автокомплитом, и излишняя магичность скоупов. Просто разделили, так как слишком много ответственности? Ну AR вообще весь такой. Тот же Фаулер гвоорит, что не видит причин выносить методы поиска в отдельный файндер из AR.
Тут очень понятная логика если сравнивать yii и yii2.
Решили не писать с нуля, а хорошенько переделать первую реализацию.
AQuery, это бывший CommandBuilder.
Хотя я бы вообще его выкинул, а сделал как в Laravel наборы правил.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Меня одного раздражают фразы типа "Фаулер сказал" без ссылок на точную его аргументацию? Мало ли кто что сказал.
вообще, риторика в стиле "херню понаписали - в Hybernate/Symfony все сделано правильно, а остальное хрень! А ну развлеките меня" не имеет перспектив осмысленного диалога

так уж вышло, что выделение finder из AR придумал я года 3 назад, но объяснять это здесь я не буду
 
Последнее редактирование:

MiksIr

miksir@home:~$
Меня одного раздражают фразы типа "Фаулер сказал" без ссылок на точную его аргументацию? Мало ли кто что сказал.
Обычно это раздражение вызывает у тех, кто сам не читал и делать ему это лень, ибо он считает, что и так все знает, либо в крайних стадиях звездной болезни. Мне казалось, что конкретно вы не из их числа. В общем можно пойти и почитать и без проблем найти это место, разве нет? Статья про AR в P of EAA не очень большая.
Да и, как я говорил тут уже, при наличии отсутствия внятной аргументации, я выберу сказанное Фаулером, а не grigori и уже тем более Вурдалак. О, аргументация может многое изменить, да, только последние ей тоже не страдают.
 

MiksIr

miksir@home:~$
Тут очень понятная логика если сравнивать yii и yii2.
Решили не писать с нуля, а хорошенько переделать первую реализацию.
AQuery, это бывший CommandBuilder.
Хотя я бы вообще его выкинул, а сделал как в Laravel наборы правил.
Мне в общем не нравится не то, что они AQ вынесли в отдельный слой, а то, что Model::find() возвращает его и дальше мы работаем именно с ним. Можно было бы через агрегацию, например, сделать. Как минимум две причины, почему мне, как разработчику, это не нравится - я сформулировал: IDE-friendly и неявность описания скоупов. Они не критичны (даже IDE можно победить, если делать ModelActiveQuery), но в чем плюсы для разработки?
 

fixxxer

К.О.
Партнер клуба
Я не о лени, а о важности контекста таких высказываний. Без контекста выглядит безусловной ссылкой на авторитет, что не способствует здоровой дискуссии.

Upd. Что у Фаулера я примерно помню, лично мне потребуется усилие чтобы пробраться через винегрет yii-статиков с целью анализа yii-реализации на соответствие каноническому AR, и я не уверен что готов этим заняться:)
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Ну да, вот контекст:

In an initial design for a Domain Model (116) the main choice is between Active Record and Data Mapper (165). Active Record has the primary advantage of simplicity. It's easy to build Active Records, and they are easy to understand. Their primary problem is that they work well only if the Active Record objects correspond directly to the database tables: an isomorphic schema. If your business logic is complex, you'll soon want to use your object's direct relationships, collections, inheritance, and so forth. These don't map easily onto Active Record, and adding them piecemeal gets very messy. That's what will lead you to use Data Mapper (165) instead.
Find-методы там именно в контексте "isomorphic schema". Примеры у Фаулера простые - статический метод, который находит в базе одну строку и возвращает new self.

Это просто и очевидно.

А когда речь заходит о растущем из рельсов "расширенном" AR, умеющем связи, коллекции и прочее - таких паттернов я не помню.
 

fixxxer

К.О.
Партнер клуба
Кстати, у Фаулера забавно. Совершенно магическим образом ниоткуда в статическом методе, причем в языке, в котором нет LSB, появляется инстанс db. :)
 

MiksIr

miksir@home:~$
А в чем принципиальное различие с той же Yii1 реализацией? Просто усложение в области find-ов, дополнительный слой работы с базой и т.п. - но это и понятно, в PoEAA все же пример, а не реальный кейс. Если вообще разбираться в том, что он пишет про DM vs AR, то там основная идея - когда модель не ложится на таблицу. Т.е. грубо говоря когда данные в модели зависят от нескольких моделей. Relation-s в AR, имхо, не то же самое - там просто ссылка на объект или массив объектов другой модели.
 

fixxxer

К.О.
Партнер клуба
Это вполне реальный кейс, хоть и упрощенный. В моем фреймворке нет никаких sql-билдеров, и все делается относительно близко к этому примеру, хотя там не совсем ar.

Я не просто так написал этот код. Обрати внимание на статические методы. Что изменится, если методы find* переименовать в load* и сделать не статикой? Да ничего, будет записано (new User)->loadById($id). При этом статические методы можно и вернуть, как обертки для быстрого вызова:
PHP:
$self = new self;
return $self->loadById($id) ? $self : null
Это к вопросу о статике. Теперь вернемся к датамапперу и yii.

Формальное отличие DM от AR в разделении: вот у нас модель (value object плюс бизнес логика), а вот отдельно персистенция и загрузка из стораджа. Суть же в том, что связь 1:1 между моделью и маппером отсутствует (иначе получилось бы то же, что AR тупо разделенный на два класса). При этом, методы find* вызываются у маппера, а он возвращает модели или коллекции.

Теперь внимательно посмотрим на внешние интерфейсы Yii.

PHP:
// find all rows satisfying the specified condition
$posts=Post::model()->findAll($condition,$params);
На AR это совсем не похоже: AR так делать вообще не умеет. Но очень похоже на DM. Просто мысленно меняем Post::model() на new PostMapper.

Так что, фактически, разделение в yii2 - это, по сути, переход к DM. А с учетом того, что у нас все-таки автоматизированное построение запросов по схеме модели, не вижу ничего странного в том, что модель возвращает свой маппер.
 

Вурдалак

Продвинутый новичок
Так что, фактически, разделение в yii2 - это, по сути, переход к DM. А с учетом того, что у нас все-таки автоматизированное построение запросов по схеме модели, не вижу ничего странного в том, что модель возвращает свой маппер.
Угу, это как в одном малоизвестном фреймворке:
PHP:
$book = Book::dao()->getById(1);
Найдите 10 отличий.

Но DM — это ж оверхед, давайте всё в один класс запихаем, хуже уже не будет.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Не, ну вообще, DM, низведенный до завязки на парную с ним модель, вполне может жить в том же классе. Два тесно связанных класса, которые хрен расширишь, ничем не лучше одного.

Тут сама проблема в том, что DM делается из AR: прямой маппинг структуры таблицы на объект никуда не девается. "Правильный" DM полностью абстрагирует от того, как мы храним данные. В onphp, насколько я понимаю, ::dao() можно перегрузить запросто.

Но все равно это будет скорее DM, чем AR. Вот такой вот хреновый DM ;)

Хотя вообще надо посмотреть, что там в yii2 понаписали, может, и расширяется оно.
 
Последнее редактирование:

MiksIr

miksir@home:~$
На AR это совсем не похоже: AR так делать вообще не умеет. Но очень похоже на DM. Просто мысленно меняем Post::model() на new PostMapper.
Почему не умеет? Если AR не умеет - то и DM не умеет, я что-то не встречал нигде информации о том, что DM отличается от AR широтой find-ов. Плюс DM еще занимается и сохранением модели. А файндер есть везде, и его функционал нигде не оговаривается.
Нет, я могу согласится, что навязывая различные виды find-ов мы усложняем класс AR, но в случае с DM будет такая же фигня. Так что функционал фандера не имеет отношения к различиям AR и DM.
 
Сверху