Alto Coding Style

Тихой сапой начал создавать документ с громким названием «Alto Coding Style» — правда, пока только начал с системы именований. Такую работу, конечно, нельзя сделать быстро и одному, поэтому проект находиться на github — здесь .

Просьба ко всем неравнодушным корректировать, добавлять, удалять…. Даже если Вы далеки от программирования, то можете проверить на орфографию и стиль изложения, например ).

Да, не забываем, что редактировать тексты можно прямо на github-е.

Обсуждать предлагаю в комментариях к этому топику.

Похожие статьи

  • Стиль кодирования
    Общая схема имени переменной выглядит следующим образом: префикс+ДополнительныйПрефикс+ИмяПеременной+Суффикс. Имена переменных содержат латинские буквы верхнего и нижнего регистров и начинаются с префикса, записаного ...
  • Проксирование псевдовызовов
    Вчера при обсуждении Alto Coding Style aVadim высказал мысль Вообще, в далекой перспективе мне хотелось бы изменить синтаксис псевдовызовов методов моделей и писать так: $this->ModuleUser->getUsersByFilter(); ...

24 комментария

+1
Респект!
+2
Отлично! И название совсем не громкое, а вполне себе нормальное, как и должно быть. Зенды, правда, подобный документ называют Standard, но мы не будем так жестко, пусть будет Style, т.е. не жесткий стандарт, а рекомендуемый стиль.

Теперь по существу: все ж префикс переменной указывает на ее тип, а у мепперов и сущностей тип — object. Поэтому вводить специальные префиксы «e» и «m» вряд ли стоит, пусть для объектов будет только «o». Но можно допустить использование двойного (расширенного) префикса типа, если сильно хочется — «oe», «om». Тогда человек, не знакомый даже с документом, но знакомый с венгерской нотацией и типами данных в PHP, легко может догадаться, что это экземпляр объекта.
0
В комментариях к прошлой статье extravert сказал, что для составных префиксов еще не время, и я с ним согласен. Сущности используются очень часто и писать две буквы вместо одной хуже.

По поводу разработчиков — если будет неопытный разработчик — то он, независимо от документа, будет давать имени $s1, $l67 по ему ведомым причинам, опытный разработчик, полюбому, ознакомится с общедоступной документацией.

На счет мапперов (тоже меня опередили) — я пишу статью по стилю кодирования мапперов и вот цитата -«Каждый маппер имеет одну основную таблицу БД с которой он работает». Вторая циатата «Имя маппера состоит из префикса m и имени таблицы БД, представленной в горбатом регистре.»

Исходя из архитектуры LS, модуль может иметь много мапперов — я предлагаю оставить за каждым маппером свою таблицу. (Перекрёстные запросы пока обдумываю)
0
В комментариях к прошлой статье extravert сказал, что для составных префиксов еще не время, и я с ним согласен. Сущности используются очень часто и писать две буквы вместо одной хуже
Ну так что у нас в префиксе? Тип? Или не тип? Очень не хочется мешать в кучу типы и классы

я предлагаю оставить за каждым маппером свою таблицу
Хм, неожиданно. Но пока не вижу серьезных резонов для такого шага
0
Получается, что у каждого модуля может быть куча сущностей, но все они пользуют один маппер. Нужно определиться — маппер своим функционалом обеспечивает сущность или модуль. Если модуль, то почему маппер представляет собой свойство модуля, как доп. объект, а не является частью его функционала напрямую через методы?

Вводя требование mapper-таблица я могу объяснить:
— принципиальную возможность многих мапперов;
— отдельную папку для одного-единственного файла маппера;
— префикс m — как тип свойства (свойств с этим типов может быть моного).

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

Если модуль, то почему маппер представляет собой свойство модуля, как доп. объект, а не является частью его функционала напрямую через методы?
Самый простой ответ — так исторически сложилось. :) Не могу сказать наверняка, какая первоидея лежала в разделении, но могу предположить, что изначально задумывалось в модели (как она формулируется в MVC) абстрагировать функционал получения данных из источника с тем, чтобы можно было в перспективе использовать различные способы хранения и извлечения данных — SQL, noSQL, XML, etc.
0
Да, сущность ни в коем разе не является эквивалентом записи, но тут есть такая двойственность логики: Сущность получается ядром CMS от массива данных
$aTalks[]=Engine::GetEntity('Talk',$aRow);

Ровно также сущность может быть получена от любого массива, но по факту используется от записи таблицы!

В отношении сущности маппер — конструктор сущности.

В отношении модуля маппер — поставщик данных.

При разделении маппера по таблицам можно конкретизировать поставщика данных для модeля ($mUser, mBlogUser) и поставить однозначное соответствие сущности.

Я согласен, что сам маппер, по сущности своей, просто средство связи между БД и другими объектами — какими бы они не были, но так как маппер работает с таблицей, то, на мой взгляд, удобнее было бы разделить код. Это бы уменьшило объем кода в мапперах (и увеличило количество фалов), но сделало бы архитектуру более прозрачной.
0
по сущности своей, просто средство связи между БД и другими объектами
Нет, не БД, а источник данных, это авжный момент, т.к. я писал мапперы, которые работают НЕ с БД (в некоторых случаях это оправданно).

но так как маппер работает с таблицей...
Ни в коме случае! Если источником данных выступает все же БД, то маппер (как правило) работает с SQL-запросом, а не с конкретной таблицей. Это принципиальный момент.

И вообще, у меня такое впечатление, что Вы сейчас придумываете ОРМ, а он уже придуман и даже реализован :) Посмотрите в сторону EntityORM. Вот там источник данных завязан как раз на сущность. Но это два разных подхода к оперированию данными, которые живут параллельно, и не вижу смысла их смешивать
0
Кроме БД я других источников в LS/Alto не видел — мы говорим применительно к этой LS.

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

Да, маппер не работает с таблицей,маппер получает данные одному ему лищь ведомым способом — и другим объектам даже не нужно знать как и откуда они получены, но я ниже написал, что маппер дает данные и сущности и модулю — а это разного сорта данные.

Пока не готов продолжать обсуждение. Нужно подумать.
0
Очень не хочется мешать в кучу типы и классы
Сама венгерская нотация подразумевает определение префиксов типов конкретной среды (префиксов как типов данных, так и пользовательских типов данных), поэтому мешанины не будет — будет своя нотация не для PHP вообще (а ее и нет), а нотация для Alto.
0
Методы
Как-то сомневаюсь насчет get/set в нижнем регистре для сеттеров/геттеров.

Вообще, мне гораздо больше нравится для методов классов использовать lowerCamelCase. Но т.к. нам нужно использовать имена методов в «псевдовызовах» типа User_GetUsersByFilter(), то лучше, конечно, юзать UpperCamelCase (написание типа User_getUsersByFilter() — по мне как-то совсем не айс).

И в этих условиях выбирать регистр символов для разных случаев?
function GetUsersByFilter() { } // в модуле
function getUserName() { } // в сущности

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

Итого, мое мнение: один из двух вариантов — либо во всех методах lowerCamelCase, либо — UpperCamelCase. Но «псевдовызовы» однозначно должны быть вида User_GetUsersByFilter()
0
Геттеры как setter-ы используются только от объекта, то есть
$eUser->getId()
. Через магические вызовы я тоже не хочу использовать, через них только методы модуля, а они, как-раз, с заглавной.

Вы опередили меня в Рекомендациях — GetUsersByFilter() — это, на мой взгляд, не геттер. Геттер получает свойства приватного (защищенного) свойства через обработку его значения, а здесь, в Вашем примере, Get — имя метода, а не префикс геттера. (Подробнее поясню позже, когда допишу статью сущности).
0
GetUsersByFilter() — это, на мой взгляд, не геттер...
Да, это однозначно не геттер, даже обсуждать нечего, я лишь для примера привел, чтоб показать, что в одном случае тут метод класса, который начинается с «Get...», а в другом — метод класса, начинающийся с «get...». Но вообще геттеры/сеттеры в данном движке пока только в сущностях (Entity) предполагаются. Более того, это, как правило, некая надстройка над родительскими методами Entity->getProp()/Entity->setProp().

Но значит ли это, что все методы сущности должны писаться в lowerCanelcase, как считаете? Ведь в общем случае у сущности могут быть и иные методы, не только геттеры/сеттеры. Как предлагаете их писать?
0
Нет, у сущности могут быть приватные методы, начинающиеся со знака подчеркивания и публичные, например метод валидации сущности, я предлагаю начинать с LowerCase, только геттеры и сеттеры, а остальное, только через Зглавную. Например:
<code>$sLogin = $eUser->getLogin();</code>
но
<code>$bResult = $eUser->Validate();</code>
Отредактирован:
0
я предлагаю начинать с LowerCase, только геттеры и сеттеры, а остальное, только через Зглавную
Есть какая-то аргументация или так больше нравится? Может, сделать так: в объявлениях методов всегда использовать lowerCamelCase, а составных псевдовызовах эти же методы писать через UpperCamelCase? Т.е. так:
Class ModuleUser {
    function getUsersByFilter() { }
}
Но псевдовызов этого метода оформляется так:
Но вызов оформляется так:
$this->User_GetUsersByFilter()
Вообще, в далекой перспективе мне хотелось бы изменить синтаксис псевдовызовов методов моделей и писать так:
$this->ModuleUser->getUsersByFilter()
Но это сугубо личные предпочтения
0
Вообще — не принципиально.

Просто для PhpStorm есть плагин LS, который доставляет автокомплит по магическим методам, но Заглавные и строчные он различает, поэтому я для себя определил, что с маленьких только геттеры/сеттеры.

С другой стороны геттеры и сеттеры — особый вид методов и обособленная нотация для них смотреться как-то отличительно не будет.

Я сам привык начинать имена (как методов, так и переменных) с маленькой буквы — и еще раз скажу — позиция моя здесь не принципиальна.
0
Вставлю своих 5 копеек. Считаю, что:
1) Префикс у мапперов и сущностей необходимо оставить «o» (object), ибо приблизительно 90% обращений к объекту — это обращение именно к сущностям (Entity), и затевать разграничения в названии префикса ради оставшихся 10% не стоит. Кроме того, венгерская нотация создавалась не для слепого следования ее рекомендациям, а что бы облегчить жизнь разработчикам. Приведенный выше пример — тому подтверждение.
2) Абсолютно согласен, что геттеры/сеттеры необходимо называть с маленькой буквы, а названия всех функций (даже которые начинаются с таких «префиксов» (что префиксом не является, но может ввести в заблуждение), как «Add», «Get» и т.п.) — с Большой.
0
С пунктом 2 согласен, с пунктом 1 нет.
Я постараюсь в ближайшее время перевести один из плагинов в нотацию, которую я предлагаю, а там — по коду можно будет обсудить более предметно.
0
Окей. Создавайте документ ACS — а там уже по ходу дела дальше обсудим.
+1
Вопрос по поводу разделения маппера по таблицам снимается.
Свел использование таблиц мапперами в такую сетку:

Видно, что маппер действительно жестко не привязан к какой-либо таблице.
+1
Как раз читаю про разные стандарты. Вопрос: почему бы вместо траты времени на написание не позаимствовать что-либо из
github.com/getjump/fig-standards/blob/master/accepted/PSR-0.md
<a href=«github.com/getjump/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md»
rel=«nofollow»>github.com/getjump/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md
github.com/getjump/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md
Pear, Zend и т.д. Проанализировать и взять лучшее.
Отредактирован:
+1
почему бы вместо траты времени на написание не позаимствовать что-либо из...
«Позаимстовать» что-то из стандарта и «перейти полностью» на какой-то стандарт — это разные вещи. Мы как раз «заимствуем». Например, общий стиль, принятый у нас в команде, базируется на стандарте Zend'а. Поддержка PSR-0 для библиотечных классов встроена в движок. Но есть ряд причин (как объективных, так и субъективных), почему невозможно (или нежелательно) просто слепо следовать какому-то одному уже существующему стандарту.

Проанализировать и взять лучшее
Анализ несомненно имеет место быть. Но вот «лучшее» без конкретизации — это сугубо субъективный критерий. Например, в отличии от приведенных стандартов, я считаю использование «венгерской нотации» хорошей практикой в PHP. Но знаю людей, которым это категорически не нравится.

Поэтому я считаю, что необходимость в собственном стиле — Alto Coding Style — реально существует. И работа по его созданию обязательно будет доведена до конца.
0
Вы, правы, но я немного о другом. Я лишь отговариваю от написания с нуля. Предлагаю не создавать документ топик-стартеру, а ознакомиться с существующими стандартами. После их анализа выдать нечто ниже написанное.

AltoCMS coding style, в основном, следует стандартам определенных в PSR-0 для библиотечных классов и базируется на стандарте Zend. Однако есть ряд причин (как объективных, так и субъективных), почему невозможно (или нежелательно) просто слепо следовать какому-то одному уже существующему стандарту. Эти причины перечислить. И далеее описать отличия.

Если говорить по-другому, то отнаследоваться от одного или нескольких стандартов с переопределнием некоторых пунктов(именование классов, методов, переменных, скобки и т.д.)
+1
Я не писал документ с нуля и придумывать что-то новое и оригинальное смысла не вижу, да и не получиться. Да в документе нет ссылок на то, откуда, из каких рекомендаций, взят горбатый регистр или использование/неиспользование префиксов и т.д., но если это принципиально, то я могу сказать что предложные принципы именования были определены исходя из:
— анализа кода CMS Livestreet,
— анализа кода Alto,
— кода фреймворка Yii (как пример кода, где не используется венгерская нотация),
— API Windows (как пример использования венгерской нотации),
— стандарта кодирования Zend,
— стандартов PSR,
— материалов интернет — в частности habrahabr.ru/post/38214/,
— книги «Совершенный код» Стива Макконнелла
— опыта собственной практики.

Предложение я сделал для того, что бы внести некоторую определенность в структуру кода, поскольку видно (если вчитаться в код) что какие-то правила и соглашения авторы CMS и плагинов используют, но они, эти соглашения, нигде не зафиксированы.

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

Заметьте, я предложил только систему именования — даже не предложил. а сформулировал уже существующий, сложившийся порядок, например документ variables.txt:
— В общих положениях сформулирован принцип венгерской нотации, по которой нет четких требований так как это не стандарт, а подход.
— Префиксы — анализ кода Alto и LS выдал их список (Да я открывал код каждого модуля, маппера и сущности, читал этот код и встречающиеся префиксы выписывал на бумагу). Могу сказать, что других префиксов в этих CMS нет.
— Суффиксы-Исключения определены по тому же принципу.

Вопрос? Что именно из этого документа мне привязать к какому стандарту.

Если подытожить вышесказанное документ variables.txt представляет собой сформулированный принцип венгерской нотации для CMS Alto.

Тоже самое можно сказать и про документ db

В последнем документе classes.txt используются выдержки ZEND+PSR, но тут тоже вопрос? константа большими буквами пишется и в С++ то требование пошло от него.

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