Как стать автором
Обновить

Комментарии 33

>Мы же не используем голый SQL, где его вполне легко можно заменить AR`ами или теми же query builder`ами?

Используем. Не используем, как-раз, AR/Builder/ORM. В остальном, с постом согласен: в случае с конфигами билдер будет удобен (при использовании кеширования, конечно-же).
Я имел в виду что-то типа как здесь у нас написано: www.yiiframework.com/doc/guide/1.1/en/database.ar
Although Yii DAO can handle virtually any database-related task, chances are that we would spend 90% of our time in writing some SQL statements which perform the common CRUD (create, read, update and delete) operations. It is also difficult to maintain our code when they are mixed with SQL statements. To solve these problems, we can use Active Record.
Ужас какой. Это вы называете человеко-читаемым?

Посмотрите в сторону YAML, пожалуйста.

У него есть ещё один громадный плюс, — одним и тем же конфигом можно пользоваться из приложений на PHP, Python, Perl, Ruby, Node.JS etc.
Проблема yaml`ов и прочих «не-методных» конфигов в их недокументированности in-place.

Я открываю yaml и при наведении на любой участок текста получаю ничего. Тоже и в XML`ях и простых массивах.

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

Основная суть в том — чтобы иметь in-place доки и code completion.
Если не полениться и написать схему к xml, то ide будут вполне сносно дополнять теги и атрибуты.
Пример в студию пожалуйста! Для хотя бы поп-IDE: blablaStorm, netbeans, eclipse. А потом ещё для более изящных редакторов. Пока нету общего стандарта — хрен-то тамушки. Надо как минимум 3 версии писать, если ещё эта текущая IDE это поддерживает. Да и есть ли смысл?

И ещё раз — основная задача только сложный массив создать/передать. Давайте уже отойдем от yaml`ов и проч. Хотя это и горячо.
По поводу того, что билдеры удобнее для ряда случаев, я не спорю. Коммент был чисто по вопросам документированности.

ru.wikipedia.org/wiki/XML_Schema
Все основные IDE платформы умеют.
Скриншот

Сами то элементы — да конечно! А вот их описания — умеют ли? Хотя если вот это — оно www.w3.org/TR/xmlschema11-2/#prim.nxsd, то тогда xml`ю +1.

Но опять же: основная задача только сложный массив создать/передать.
Хотя скорее это у вас ошибка. Вы описываете DSL, язык предметной области, в данном случае язык запросов. А не конфигурацию.

Для таких языков, с учетом ограничений PHP, выглядит нормально.
Да не совсем. Если уж о конкретике, то см. тута:

book.cakephp.org/2.0/en/models/retrieving-your-data.html

В том же YII есть человечьи query-builder`ы.

Но опять же в том же YII у нас конфиги всегда массивами (и мы знаем зачем):

github.com/yiisoft/yii/blob/master/demos/blog/protected/config/main.php
Btw, вы тыкали на «Образцы конфига: ручной режим и билдер»? Я навреное зря его спрятал :)
Я слово «конфиг» зря в заголовок поставил. Ключевым здесь является именно понятие «массивного» параметра.
Не понимаю, за что минусуют, но я категорически плюсую. Делать вместо многомерныйх не структурированных массивов чёткие структурированные объекты — это признак хорошего тона, особенно, если в твоём коде будут разбираться другие программисты вооруженные топорами и бензопилами. Yaml и XML не спасут, если ты не помнишь названия переменных/атрибутов наизусть и иногда опечатываешся.

Это то же самое, что создавать константы для ключевых слов:

<?

class Image {

   const RESIZE_METHOD_RESIZE                    = 'resize';
   const RESIZE_METHOD_CROP                      = 'crop';
   const RESIZE_METHOD_CROP_TOP                  = 'cropTop';
   const RESIZE_METHOD_CROP_WITHOUT_CROPPING     = 'cropWithoutCropping';
   const RESIZE_METHOD_SOMTHING                  = 'somthing';
   const RESIZE_METHOD_ETC                       = 'etc';
   // Эти константы не нужны для какой-то логики,
   // но они нужны для автокомплита и что бы не опечататься.

}
?>


Откуда они подлецы вообще появляются?


Зачастую они появляются из-за отсутствия в PHP именованных параметров и, отчасти, параметрического полиморфизма. Ну и не любят многие ООП, предпочитая $user['profile']['name'] вместо $user->profile->name.
Да это больше скорее не язык, а дисциплина. Хотя язык если позволяет, то дисциплина тоже хромать может.

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


Все-все-все, давайте всё, что возможно именовать и типизировать по возможности, а? Массивы — злое зло! Независимо от языка. Вернее в тех языках, где можно что-то подобное сделать.

ps: Про именованные параметры имеется в виду когда у нас у метода много параметров и мы вызываем его с только нужными? Тут это не всегда спасёт, когда параметр уровневый :(
Ну так народ и программирует с использованием языка — есть необязательные параметры у метода и передают ему массив с ключами нужными.

От «уровневого» параметра (если я правильно понял) спасёт создание объектов с нужными полями. Если есть необязательные поля, то опять же конструктор с именнованными полями пригодился бы.
На мой взгляд не код должен подстраиваться под среду разработки, а наоборот среда разработки должна подстраиваться под код. пинайте разработчиков вашей ide чтобы запилили поддержку аннотаций для массивов, xml, yaml, tree и всего остального и от этого будет куда больше пользы, чем хранить конфиги в виде лапши.
Вы считаете, что хранить одновременно некие аннотации для массивов, yaml`ов и xml`ей — это лучше, чем использовать уже готовые инструменты и способы? Вот не соглашусь. Нафига в IDE изобретать велосипеды?

Как вы себе вообще видите аннотации массивов? :)) Ну как один адекватный пример в студию. Сюда же xml и yaml.

Уже phpdoc`и для массивов изобрели? А мы то не знали — ссылочку в студию пожалуста. Даже если вдруг их изобрели/изобретут — какая IDE их реализовала/реализует? Нафига микроскопом гвозди то забивать?

… среда разработки должна подстраиваться под код ...


Значит ли это, что все IDE у нас, которые не подстраиваются под г-но-код являются плохими? :)
...
    ->conditions
        ->is('Model.field', 123) // отступили
        ->between('Model.field5', 5, 5)
        ->notLike('Model.field8', '%8%')
        ->up()
    ->recursive(1) // вернулись
...


А как Ваш IDE вот здесь делает ступеньки при автоматическом форматировании?
Никак — это уже ручками. Для подобных конструкций правил не напасёшься — в любом IDE/редакторе :(
Мне очень важно, чтобы форматирование было автоматическим. Поэтому такой подход я использовать не могу. Может так попробовать.
$conditions = $this->findParams
    ->conditions(
        $this->findParams->createCondition()
        ->is('Model.field', 123)
        ->between('Model.field5', 5, 5)
        ->notLike('Model.field8', '%8%'))
    ->recursive(1)
    ->fields('Model.field1', 'DISTINCT Model.field2')
    ->order('Model.created', 'Model.field3 DESC')
    ->group('Model.field')
    ->limit(100)->page(1)->offset(10)
    ->callbacks(true)
    ->get()
;
Вариант конечно, но тогда у нас лишний код просачивается и вся красота method-chain`ов уходит :(
Хотя… Для более сложных случаев скорее всего лучше будет именно отдельные вызовы делать, а не всё в одном chain`е.

Как вариант тогда использовать плоские шорткаты, как тута:

* github.com/garex/oopconfig-cakephp/blob/develop/tests/CakePHP/FindParamsTest.php#L105

Эм… как на счёт И и ИЛИ?
Пока никак — но добавляется легко (но не быстро). Я больше концепцию подготовил, чтобы статью написать — это до продакшена ещё весьма далёко.
Так и я про концепцию. Просто интересно как будет выглядеть ветвистое условие с И и ИЛИ.
Х.з. надо будет на досуге глянуть. Как вариант можно посмотреть как в Yii query-билдер это решает. Я туда не вдавался пока.
Да, так и будем поступать…
Билдеры на самом деле часто удобнее плейн конфигов. Была когда то подобная идея: написать каркас для простого создания своих билдеров. Но в итоге отказался, показалось, что слишком уж мало функциональности несет в себе такой каркас.

ЗЫ Не увидел этой ссылки www.phptherightway.com
:) А о ней вот тока щас узнал.
То, что предложил автор — излишнее усложнение. Если на каждую не нравящаюсю нам особенность PHP писать по несколько классов для ее обхода, все будет работать с черепашьей скоростью и в 20-50 мс на запрос мы никогда не уложимся.

Паттерн Builder используется не для того, чтобы заменить массивы с конфигом (да, в динамических ЯП можно использовать массивы там, где в строгих ЯП надо делать классы и структуры ради одноразового использования), а для того, чтобы заменить конструктор или метод с 20 параметрами. Как вариант — построение запроса на выборку чего-нибудь из хранилища, например.

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

Лучшее решение для того, чтобы заменить массив чем-то строго типизированным — использование класса с публичными методами. Как бонус, получаем еще и дефолтные значения. Вот код:

class SomeServiceConfig
{
public function __set($k,$v) { throw new \Exception; }
public function __get($k) { throw new \Exception; }

/** комментарий */
public $maxConnectionNumbers = 100;
public $useSomeProtocol = false;
public $warnOnUsingSomeCommand = true;
}

(__set и __get нужны для обхода неудачной идеи в дизайне PHP, позволяющего создавать свойства динамически при опечатке в имени свойства). Пример кода, инициализирующего такой конфиг:

$cfg = SomeService::getDefaultConfig();
$cfg->useSomeProtocol = true;
$service = SomeService::create($cfg);

Эхх… Вы наверное тоже не вчитались :)

Это решение — не для адекватных систем, а для тех, которые форсят параметры быть массивами. Это значит, что на входя массивы быть обязаны.

Это значит, что мы не можем использовать что-то изящное, как вы предлагаете.

Пожалуйста, посмтрите ещё раз и внимательнее.

В что касается ваешго варианта, то именно он менее удобен:

* DI — blabl::getSoemthing()
* нету chain`ов — надо надо в коде кучу лишнего писать а-ля $cfg->bla = 1, $cfg->foo = 2, заместо одной строчки: $cfg->bla(1)->foo(2).

Про оверхед

См. соотвествующий раздел статьи. И ещё раз — это решение не для того, где мы в системе сами можем сделать — а для других систем, которые на вход требуют сложных массивов. Т.е. это решение не из-за особенностей языка PHP (или иного), а из-за особенностей других систем, которые мы можем использовать. Не всё вокруг розовое и состоит из систем, которые мы можем сами для себя подправить и юзать.

pls RTFA.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории