+25.90
Рейтинг
57.92
Сила

Алексей Качаев

Ладно заканчиваю словогенерацией заниматься…

Сказал сам себе тоже самое 5 миинут назад :) На вкус и цвет все фломастеры разные…
Легковесность-легковесностью, а программисты всегда дороже железа.
На самом деле, то что есть сейчас мало чем отличается от mysql_query. DbSimple просто выполняет «черную» работу, но не добавляет никакую новую логику в работу приложения.

В этом есть серьезные неудобства, для того чтобы это понять достаточно написать пару модулей… Но это не смертельно, посмотрите на WordPress — живет процветает с 10 тысяч стронних плагинов, а работает до сих пор на $db->query();
Вы можете наследовать sql и tpl?


Да, могу. На примере SQL. Пишется класс, к примеру, SQL, объект которого может «собирать» по кускам ваш запрос,
$select=new SQL();
$select->select(array('login','pass'));
$select->from('users');
$select->where('id=',5);
$select->build(); // тут выдается SQL


Далее делаете в SQL функцию init(), которая загружает стандартные (базовые) составляющие. Потом наследуете этот класс, перегружаете init(), добавляя новые составляющие (только сначала вызвав parent::init()).

Вот вам и наследование SQL. Tpl — все тоже самое.
Лично я постоянно пользуюсь наследование вида и функционала Web Form, реализованное через Zend_Form.
Я об этом и говорю :) Спор то и начался с моих слов
НАСЛЕДОВАНИЕ КЛАССОВ = ЛУЧШИЙ КОДОГЕНЕРАТОР

том как сделать ЛС лучше)

В этом-то мой вопрос: как AR сделает LS лучше? :)

Проблема работы уровня Models в LS в том, что нет общей платформы — каждый mapper пишется так или иначе «с нуля». Равно как и каждый новый Entity. По хорошему здесь нужно писать хороший DB-layer со своим объектом row (строка таблицы) и rowset (набор строк) — а в дальнейшем оперировать наследованными от него объектами.

А там дальше начинается та область, где граница между Data Mapping & Active Records становиться очень тонка :)
Наследование классов это другое, нежели генерация.

Вы уверены?
Генерирование — это создание кода исходя из а) ранее созданных форматов, б) переданных параметров кастомизации.
В наследовании мы получаем тоже самое — мы переносим ранее созданный формат (экземпляр) логики, кастомизируя его.

Вот если бы кодогенератор мог создавать логику кода, которая изначально не заложена в него… тогда это был бы уже говорили об искусственном интеллекте, пишущем программы по нашей просьбе. Но человечеству до этого еще далеко.
Интересно, а как кодогенерация может помочь избежать использования eval()?
2. data mapper, насколько я знаю, это вынесение запросов в отдельный класс, который позволяет абстрагироваться от базы данных всё приложение.


Нет. Суть дата мепинга объясню на конкретном примере сущности «User». У вас есть две стороны барикады:

1) приложение, для которого User это «что-то» («нечто»), имеющее определенные характеристики (имя, логин, пароль, ...), определенные права, совершающее определенные действия, и меняющееся при совершении этих действий;

2) база данных, для которой пользователь — это только строка в таблице и несколько смежных ячеек. И все.

Паттерн Data Mapper подразумевает, что для наведения порядка вы — а) имеете класса UserEntity, инкапсулирующий в себе характеристики и действия объекта приложения; б) UserMapper — который может превратить объект UserEntity в строку данных в реляционной базе данных, и наоборот, читая строку(и) базы вернуть вам нормальный UserEntity.

То, что SQL выносятся в отдельный файл, это следствие, а не причина.
Даже если мы выбираем данные из одной таблицы, то JOIN все равно никто не отменял :)
Этот паттерн работы с базой называется Data Table Gateway. Суть в том что таблица из базы отображается в нашем приложении объектом некоего класса. Мы учим этот класс доставать записи, находить, вставлять и обновлять и дальше работаем уже не с ТАБЛИЦЕЙ, а с ОБЪЕКТОМ нашего класса. Связи в базе (refference) переносятся на связи между объектами (reference map).

Т.е. класс UserModel работает с таблицей users, BlogModel — с таблицей blogs. Если на уровне данных есть связь между пользователями и блогами, то работаем не с этой связью, а со связью UserModel <-> BlogModel.

Чаще всего используется в совокупности с Data Row Gateway. Очень неудобно, когда сущность «размазана» в базе по таблицам или поддается динамической кастомизации.
ROR это классно! Поддержу автора в этой идеи.

Теперь выскажу свое мнение по предложениям:

1. Convention over configuration — вопрос косвенно поднимался в комментариях к топику в о нововведениях. Сейчас система слишком динамично меняется, чтобы говорить о каких-то глобальных Convention, а локально это уже внедряется — например, routing rewrite.

2. Active Record — это только один из паттернов связки реляционнки и логики приложения. В LS используется data mapper, дело стиля, какие выгоды по вашему получит приложения от перехода на AR?

3. Генераторы. Мне тоже раньше эта функциональность импонировала, но долгий опыт работы с фреймворками меня научил — НАСЛЕДОВАНИЕ КЛАССОВ = ЛУЧШИЙ КОДОГЕНЕРАТОР. Главное правильно смонтировать каркас, и не это касается не только CRUD.

Да, стандартный CRUD можно сделать на ROR за минуту-две. Но у меня под ZF есть каркас приложения, на основе которого я реализую CRUD минут за 5. При том, что этот вариант мне нужно будет гораздо меньше «допиливать», и он более функционален.
/rss/tag — топики по конкретному тегу.
/rss/comments/ — комментарии к конкретному топику. Вам выше приводили ссылки.
смотрите код /classes/actions/ActionRss.class.php
Повнимательнее изучите конфиг. Для наглядности просто выведите его на печать print_r(Config::Get()).
$config['entity_prefix']  = '';
$config['sphinx']['host'] = 'localhost';
$config['sphinx']['port'] = '3312';

определено в файле /config/modules/search/config.php — т.е. это конфигурация модуля. При отработке /config/loader.php этот массив будет слит в конфиг с префиксом 'module.название_модуля'. В итоге получим на выходе (кусок конфига):

[module] => Array
        (
            [blog] => Array
                (
                    [per_page] => 20
                    [personal_good] => -5
                    [collective_good] => -3
                    [index_good] => -8
                )

            [topic] => Array
                (
                    [new_time] => 86400
                    [per_page] => 10
                )

            [user] => Array
                (
                    [per_page] => 15
                )

            [comment] => Array
                (
                    [per_page] => 20
                    [bad] => -5
                    [max_tree] => 7
                )

            [autoLoad] => Array
                (
                    [0] => Cache
                    [1] => Session
                    [2] => User
                    [3] => Lang
                )

            [search] => Array
                (
                    [entity_prefix] => 
                    [sphinx] => Array
                        (
                            [host] => localhost
                            [port] => 3312
                        )

                )

        )
Или загружать список существующих Actions при инициализации роутера (или при загрузке конфигов)…
И ооочень медленно движется вперед.

Если смотреть на CI, то лучше — KohanaPHP (это самостоятельная ветка CI), но тут обратная проблема — слишком быстрое развитие — дока сильно отличается от реального состояния вещей.
Частично решается этим
livestreet.ru/blog/addons/1956.html
1. Этот вопрос обсуждается. Мое видение — $config['router']['page'] — должен быть по умолчанию пустым, как и ['rewrite']. Но функционал за ним все равно должен оставаться, на случай, если пользователю понадобиться использовать кастомный Action, или вообще что-то самописное.

Т.е. пользователь написал свой Action для отображения блога и поставил —
$config['router']['page']['blog']='ActionMyCoolBlog'

А потом еще и захотел, чтобы доступ к нему был не через /blog/, а через /superblog/ — добавил
$config['router']['rewrite']['blog']='superblog'


Помимо удобства здесь есть еще одно преимущество — конфиг роутера теперь можно «перекрыть» из конфига модуля. Т.е. можно писать модули, которые будут «подменять» стандартные action`ы в автоматическом режиме, без необходимости вносить правки в основную конфигурацию.

а системе не надо будет инклудить лишний файл

Экономия на спичках. Все равно каждый раз при загрузке конфигураций модулей нужно проверить существует такой файл или нет.

2. Масштабируемость. Сколько контента вы уместите в одном каталоге?

Пока в этом направление ничего не реализовано, но плацдарм готов — /uploads не имеет жесткой привязки, может быть сменена через Config::Set()… Пишите мини-файловый-сервер, распределяющий и тянущий контент с разных серверов, если на одном места не хватает.

LS по своей специализации должна быть максимально просто масштабируемой, иначе ваше «блого-социальное сообщество» быстро разрастаясь наткнется на серьезные технические трудности.
В Zend`e роутер по умолчанию работает /:module/:controller/:action/:param1/…
Где module — это типа «application внутри application». Во многом отсюда в MVC терминологию перешло понятие Module, которое представляет из себя некую инкапсулированную mvc-связку. В LS мы под модулем понимаем совсем другое :)

Т.е. по вопросам имен и терминов можно долго разбираться — смотря как глубоко копать в эту тему.