Pull to refresh

Comments 56

Я знаю, что есть namespace'ы.
Только не совсем понимаю, как они мне помогут найти модель User согласно тем условиям, которые я указал в топике?
Смотрю первые комментарии, и не понимаю — кто-нибудь вообще читает текст топика, а не только заголовок?
Я же привёл примеры, когда Find Usages не сработает.
Давайте по порядку:
public function actionGetData($object_type) {
    $model_class = 'Wb' . $object_type . 'Model';
    $model = new $model_class();
    return $model;
}

При нормальном построении кода, такой метод должен возвращать объекты с интерфейсом
Wb\Model\ModelInterface. В таком случае вы можете написать phpDoc комментарий, где укажете названия интерфейса.

Если же не использовать функционал Find Usages в IDE, то обычным поиском по тексту можно найти вхождения полного имени класса(Wb\Model\User). Оно встретится либо в секции uses файла, либо непосредственно в месте использования.
Не понимаю, как для этого участка кода будет написан лаконичный phpdoc?
/** var User|LogisticUser|CatalogItem|CatalogCategory|StoreItem */

То есть, перечислить все возможные классы, ещё и с нэймспэйсами?

Собственно, касаемо этого кода процитирую из моего топика:
особенно считаю большим злом, когда ссылка на класс генерируется из объединения строк – это нельзя найти ни через «Find Usages», ни через поиск по тексту
Если метод может возвращать User|LogisticUser|CatalogItem|CatalogCategory|StoreItem — это сигнал, стоит задуматься, возможно вы что то делаете неправильно
А я разве не это написал?
Причём, даже два раза — один раз в топике, другой раз — в комментарии.
Все просто, такой метод должен возвращать объекты, которые имеют один и тот же интерфейс, тогда в phpdoc вы укажете

/**
 * @return Module\Entity\BaseEntity
 **/


Если он возвращает совершенно разные объекты, то метод нужно заменить на несколько методов.
Про phdoc'и я знаю, и что в return писать тоже знаю.
Стараюсь максимально покрывать ими код, в том числе и внутри методов, например, когда используется switch case.

А насчёт разных объектов…
Собственно, это я и имел ввиду, когда писал, что ссылка на класс через объединение строк — это плохо.

Только, не могу понять логики минусующих/плюсующих…
<?php

namespace Wb\User;

class Model {

}


<?php

namespace Wb\Models;

class User {

}


И почитайте про PSR-0
Есть два нэймспэйса с одинаковыми классами User.
Один — в Logistic, другой — в Site.

И как мне найти класс User, который относится к Site?
Ведь, как я написал в топике, нет ссылок на класс, есть только строка с текстом 'User'?
А ещё в контроллере используется $_POST['User']…
Не понимаю, как нэймспэйс разрулит эту ситуацию.
<?php

namespace Vendor\NameSpace;

class SiteUser extends User {

}



<?php

namespace Vendor\NameSpace;

class LogisticUser extends User {

}
Извиняюсь, конечно, но если использовать такой вариант, то причём тут namespace?
Какую роль он играет в решении задачи?
Действительно, поставить минусы легче, чем написать, причём тут нэймспэйсы.
Я упомянул про БЭМ ещё в самом начале топика, но БЭМ — это больше к разметке, нежели к алгоритмам.

Про php вообще молчу
Не понял, что этим имелось ввиду.
Использование id для разметки страницы не очень хорошая практика. Все стараются всё завязывать на классах. И хотелось бы увидеть пример кода где идёт стилизация большого блока, из 10+ классов

Не понял, что этим имелось ввиду
Префиксация портит всю красоту кода
>>Использование id для разметки страницы не очень хорошая практика. Все стараются всё завязывать на классах.
Не соглашусь, не все.
Во-первых id даёт понимание, что элемент один и стили можно смело менять.
Во-вторых когда css и html Действительно много, использование # в некоторых местах, хоть немного, но может повысить производительность.
И постоянно нужно помнить о весе селекторов, не так ли?
Заметьте разницу между вашим и моим сообщением — вы категорично указываете «Все стараются», я лишь не соглашаюсь «Не все».
>>И постоянно нужно помнить о весе селекторов, не так ли?
Лично я постоянно помню — это не сложно и меня не напрягает, если вы не хотите — не помните.
Чтобы объяснить, почему мне нравится использовать # приведу пример:

Представим себе сложную форму с некоторым количеством разных кнопочек, инпутов и т.д.
Некий дизайнер интерфейсов отрисовал ее, задумываясь об удобстве пользователя.
В результате у нас куча разных отступов, разные высоты элементов и тд.
Если мы используем для всего классы. у нас будет примерно как-то так:
<button class="button_form_edit button_save">
<button class="button_form_edit button_check">

Человек который потом придет и захочет кнопочку сдвинуть, должен будет проверить а точно ли нигде «button_check» не используется.
Что тут помнить — идентификатор превыше класса.
Да и, наиболее используемых не так много.

Что касается «всё стараются завязывать на классах»…
Чем преимущество завязывания кнопки корзины на классы перед идентификатором?

Или ещё какой-нибудь блок, который уникален для сайта.
Например… блок сверху информацией о пользователе.

Я считаю, что идентификатор даёт другому программисту/дизайнеру понять, что этот элемент — единственный на сайте.
Он уникальный, и других таких нет.
А класс… он не уникальный, их много, разных, и одно и то же имя класса может использоваться для разных элементов.
Собственно, для этого изначально и предназначались идентификаторы и классы.
>>Все CSS классы я начинаю с префикса «cl_», идентификаторы с префикса «id_».
Это то вообще зачем?? Трудно запомнить что "." это класс, а '#' это айди?

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

Цитата из моего топика:
Кстати, такой код легче прогнать через сжатие и обфускацию. Причём, не надо никаких анализаторов – ищи регуляркой по префиксам и сжимай. Собственно, поэтому и используются разные префиксы для идентификаторов и классов.
>>В HTML нет точек и решёток перед классом и идентификатором соответственно.
>>К тому же, классов может быть указано несколько через пробел.

Это какой у вас такой HTML в котором такое нужно?
В нашем обычном как бы и так все понятно:

<div class="block" id="container"></div>


>>Цитата из моего топика:
>>Кстати, такой код легче прогнать через сжатие и обфускацию. Причём, не надо никаких анализаторов – ищи регуляркой по префиксам
>>и сжимай. Собственно, поэтому и используются разные префиксы для идентификаторов и классов.

Не ясно почему легче.
Это какой у вас такой HTML в котором такое нужно?
В нашем обычном как бы и так все понятно:

Надо заменить его на что-то другое.
И как найти, где используется идентификатор «container»?
Все вьюшки, стили, JS-скрипты…

Не ясно почему легче.
Потому что есть разного рода расширения, плагины и т.п., где НЕ НАДО заменять и обфусцировать имена классов и идентификаторов.
Префиксами я отделяю свои от сторонних, и мне не надо городить большие регулярки, причём отдельно для HTML, отдельно для JS/CSS.
Чем будет принципиально отличаться container от cl_container? При этом, как вы понимаете вместо «container» может быть любое другое слово или слова.
>>Потому что есть разного рода расширения, плагины и т.п., где НЕ НАДО заменять и обфусцировать имена классов и идентификаторов.
А зачем их вообще обфусцировать? Экономия трафика? С этим просто сжатие справится лучше.
Собственно совершенно непонятно что вы вообще там делаете, почему не используете стандартные инструменты, по сжатию, минимизации, объединению файлов. Со стороны сейчас кажется, что вы решаете какие-то надуманные проблемы.

так вы что не видите куда пишете? в id или в class?
А это тут причём?
Мне надо найти и заменить — статью кто-нибудь читает?

Вот есть класс container (приведённый в комментарии выше), и мне надо его заменить.
Я открываю форму поиска в IDE и ввожу туда слово «container».
Потом ставлю, что надо искать по файлам CSS / HTML / JS / PHP.
Вываливается 100-200 файлов.
По вашей логике, мне надо открыть все файлы и глазами пробежаться по всем совпадениям и заменить.
При этом, проанализировать, действительно ли это класс, а не что-то другое (например, не переменная JS).
Так?
Не надо открывать и пробегаться. Есть же регулярки.
Например такая class="[^"]*?(container\b)

Хотя да, выше вы уже писали что в вашем случае «не надо городить большие регулярки». Но лично моё имхо что нет большой разницы между ((?:cl_)container) и тем что я написал.
Да, с заменой в HTML-файлах это поможет.

Но суть не в том, что можно регулярку в поиск указать (это я знаю).
Суть в том, что одной регуляркой тут явно не обойдёшься.

Есть же ещё JavaScript и CSS, а также PHP файлы.
И там нельзя регуляркой найти — слишком много может быть частных случаев.
Навскидку:
— addClass('container')
— $('.container').remove()
— $container.append('OK')
— container = $(this)

В итоге, всё равно надо будет открывать и анализировать каждое совпадение слова «container».

Что касается cl_container.
Поиск через регулярки нужен, чтобы провести обфускацию и сжатие.
А в работе вообще не надо никаких регулярок — вбивай в поле поиска «cl_container» — и всё, что нашлось — всё классы CSS.
Ну прежде всего не стоит мешать в одну кучу html, php, js и css. У каждого своя область использования и следовательно разные подходы к разработке. То что прокатит в html в js может выйти боком.

Ваш подход к рефакторингу по префиксам и постфиксам будет работать ровно до тех пор пока не найдётся «умник» решивший что неплохо бы иметь перменную cl_container, которая как нельзя лучше отображает что в ней содержится результат селекта по данному классу. var cl_container = document.getElementsByClassName('cl_continer')

Да, тут можно поспорить что перменная содержащая массит должна быть во множественном числе (cl_containres) или если, к примеру, использовался jQ, то надо было написать как $cl_container.

Вобщем к чему я всё это? Вы верно напсали в конце статьи что нужно обучать работать с новым сопособом наименования. А это невсегда приемлимо. Но вы — молодец. Серьёзно, без сарказма. Имхо то что вы пытаетесь сделать — разработать стандарт для наименования. И это отлично. Ну а то что он не принят хабром… Можно посмотреть на то что делает PHP-FIG. К ним была масса претензий что они выбрали 4 пробела вместо одной табуляции. И что, от этого они стали хуже? Нет. Они просто не такие как кто-то привык.

Единственное, множество стандартов этого хорошо. Плохо когда они все пытаются уместиться в одном проекте (или даже одном файле)
1.
Что значит — мешать в кучу?
У вас есть класс/идентификатор стиля — и вам его надо задействовать и в CSS, и в JS, и в PHP…

>> У каждого своя область использования и следовательно разные подходы к разработке.
>> То что прокатит в html в js может выйти боком.
Опять же, к чему это?
Это и так понятно.

2.
>> «умник» решивший что неплохо бы иметь перменную cl_container
Для этого есть регламент.
Хотя, на моей памяти ещё ни разу не встречалось таких переменных.

3.
Я не пытаюсь разработать стандарт для наименования.
Изначальная цель была — не придумать что-то, а спросить у сообщества, как они выходят из таких ситуаций.
Как они разделяют разные типы данных и именуют переменные.

Для себя я придумал такие вот префиксы и постфиксы.
И ожидал услышать адекватные «за» и «против».
Причём такие, чтобы я смог уверенно сказать «да, тут я не прав».
Пока я не увидел таких комментариев, хотя некоторые, замечу, дали повод задуматься.
Нет не так. для поиска класса container как минимум нужно будет заюзать регулярку в html и возможно в php(не знаю вашу php+css магию). А для поиска в JS / CSS можно искать как .container
В JS, как я написал выше, вы не сможете найти ВСЁ по ".container", так как могут встречаться, например, addClass('container') или вообще item.className = 'visible container'.
Таки «суффикс» скорее.
И да, в PHP такое делать, несомненно, не стоит.
>> Таки «суффикс» скорее.

Почитайте насчёт того, что такое суффикс.
Вкратце:
— Префикс — то, что идёт прежде всего — перед ним ничего нет;
— Постфикс — то, что идёт после всех частей слова — за ним уже ничего нет;
— Суффикс — то что идёт после корня, за суффиксом может быть окончание.

>> И да, в PHP такое делать, несомненно, не стоит.
Почему?
Потому что для решения этих проблем в данном языке предусмотрены другие средства.
Я уже не удивляюсь, что вы так ответили.
Я прочитал ваш первый комментарий, постарался узнать, почему вы так думаете.
Вы написали второй комментарий, из которого я тоже ничего полезного не вынес.
Не могу понять — зачем это писать?
Абсолютно на всей этой странице в двадцать экранов высотой, включая комментарии нет ничего полезного. И что дальше?
Извините, конечно, по по-моему то, что вы написали — полный п… ц.

Начнем с того, что читать это невозможно. Про писать — вообще молчу.

Допустим, есть у нас таблица user. Есть комментарии к новостям, которые пишут юзеры. Получаем relation 'comments'. Надо вывести комментарии данного пользователя.

В обычном случае, без префиксов и прочего:
1. Генерируем модели при помощи gii
2. пишем что-то вроде
foreach($user->comments as $comment) {
   echo $comment->message;
}


В вашем:
1. Генерируем модели при помощи gii
2. Заменяем все relation'ы на Relation'ы с префиксом
3. Пишем что-то вроде
foreach($user->Rcomments as $comment) {
   echo $comment->message;
}


«R» читаемости не явно не добавляет,…

А теперь представим, что модели данных что-то поменялось. А это значит модель надо сгенерировать заново, снова добавить префиксы и т.п.

Вы пишете:
Да, префиксы и постфиксы несколько замедляют написание кода, но код пишется один раз, а читается и рефакторится далеко не один. Как по мне, так значительно проще читать код, в котором можно сразу определить по префиксам и регистру, где атрибут модели, где метод, а где scope или relation.


Если вы пишете код один раз — вы гений. А вот чтение и рефакторинг как раз и замедляется. Код должен читаться как простой текст на английском, Из-за этого и не люблю массивы, когда есть возможность использовать объекты. Сравните 3 записи:
1. echo $news->author->name
2. echo $newsModel->R_Author->name
3. echo $news['author']['name']

Имхо, преимущество первого очевидно.
1.
Я генерирую модель только один раз — изначально.
Затем уже вручную добавляю все связи и проверки.
По крайней мере мне не надо проверять, что изменилось, а что — нет.
Особенно это актуально, когда модель состоит не из 10-20 строчек по-умолчанию.

2.
Соглашусь, что префикс R и написание Rcomments — это бред, читаемость резко падает.
Но я же в топике написал не так, а R_, то есть R_Comments, R_CatalogCategory.
Неужели так сильно отличается читаемость R_Comments от comments?

3.
Про $newsModel->R_Author->name — тоже верно, читаемость не очень.
Но я ничего и не говорил про именование переменных — я писал про классы.
Более того, переменная — она локальная, и глупо добавлять постфикс Model.

Массивы я тоже не люблю — и об этом я тоже написал в своём топике.
1. То есть при развитии проекта вы модель уже не генерируете, а при каждом изменении в БД постоянно вручную добавляете изменения в код?
2. По-моему, да. R_ — это информация, которая не несет никакого смысла. Вы же когда пишете не используете слов-паразитов, что часто бывает в устной речи, верно?
3. В том же Yii зачем имени класса модели добавлять Model? Если вы выполняете find гораздо лучше выглядит News::model()->find(), а не NewsModel::model()->find(), не так ли?
1.
Да, так и есть — вношу изменения вручную.
Честно, мне не сложно дописать пару-тройку строк (атрибут в phdoc, валидацию и relation).
Не всегда требуется указывать проверку или relation, поэтому вообще одна строка.

К слову, может быть у вас такого не было, но сгенерированная через gii модель опасна.
Дело в том, что gii не понимает, какие атрибуты надо разрешить редактировать, а какие нет.
И большинство так и оставляют валидацию критически важных полей типа id, parent_id, user_id и т.п.
А затем присваивают через $_POST['ModelName'].
Думаю, если вы знаете Yii, сможете понять, где уязвимость.

2.
Это не слово паразит — это префикс.
Тут более уместней сочетания «Модель пользователя», «Модель заказа», «Внешняя связь с заказом», «Внешная связь с документом».
И это, как мне кажется, более понятней, чем пытаться объяснить собеседнику, что не «пользователь, который на сайте» или «не документ word, а документ, но к заказу, а не к доставке».

3.
Тут в большей степени дело в том, что Yii использует метод, названный model.
Если же метод был бы назван по-другому, было бы даже более понятней.
К слову, мне кажется, что NewsModel со статичными переменными/константами/методами выглядит более понятней, чем просто News.
UFO just landed and posted this here
Автор скорее всего долгое время работал либо один, либо в очень небольшой команде, когда-то он или кто-то другой из его команды придумал нечто, это нечто работает и все к нему привыкли. И это нечто кажется неоспоримо правильным, т.к. используется постоянно.
Но автор показал это на хабре и для многих это решение уже спорно, поэтому и возникла некоторая дискуссия.
Автор не понимает только одного, все будет хорошо, пока он не попадет в большую организацию где используют общепринятые стандарты, либо, что хуже, в другую организацию где тоже придумали свои, но другие, стандарты.

А с бабушкиным и т.д. ну абсолютно не корректное сравнение.
Да, насчёт общепринятых стандартов и обучения я тоже думал.
И в топике указал это мнение.

Только иногда проще подсунуть под нос регламент и сказать, что надо писать префиксы, нежели научить программиста писать правильный код с phpdoc'ами и нормальными конструкциями.
Это хорошо, когда программист понимает всю логику сервиса/программы/сайта и пишет так, что не надо никаких комментариев.
Но ведь это, скажем так, редкость.

Как мне кажется, в некоторых случаях проще составить один документ на 1-2 листа с регламентом именования сущностей, чем 10-20 листов, где будут перечислены все примеры, как надо писать код, а как не надо.
Причём тут «пытается всем доказать»?
Я написал статью, в которой рассказал о том, какие способы я использую для наименования сущностей в ЯП.

Вы же своим комментарием ничего толкового не сказали.
Прочитал я ваш комментарий, увидел, что вы придерживаетесь другой точки зрения.
А какой?
Где «именно конструктивного обсуждения такого подхода», о чём я просил в конце топика?

Я нисколько не обиделся, скорее, удивился, что комментаторы то и дело говорят, что это плохо, а почему — сказать явно не могут.
Лишь бы что-то написать…
1. Мне кажется, что автор пытается решить слишком обобщенную задачу. Существующие naming conventions хороши в рамках своей предметной области. Язык ли это, верстка или описание какой-то локальной конкретной задачи.

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

3. Есть еще одна чисто программерская нотация — underscore (или куллхацкеровская), известна большинству и в основном полезная

4. Игра с регистрами и множественными числами одновременно с использованием underscore и camelCase — это как физическое явление — нестабильное равновесие, чем дальше качает в сторону, тем сложнее вернуться к равновесию.

5. Отдельно бы хотелось отметить использование множественных чисел. Критичным, как мне кажется, является то, что некоторые англ.слова в единственном и множественном числе имеют нерегулярное написание (country — countries) и тут довольно легко допустить ошибку (если IDE не подсказывает) и никакой Find Usage не поможет.

как справедливо заметил tuchk4 есть PSR-0 и подобные. Есть в своих предметных областях куча договоренностей. Разработка (в частности web) для подобных возможностей, инструментов и методологий не такая уж и молодая отрасль, чтобы не пользоваться всеми этими наработками.

P.S.: как показывает опыт Symfony уход от глобального контекста в приложении к фабрикам и IoC контейнеру — очень полезная штука. То есть пытаться до сих строить приложение в глобальном контексте (про верстку молчу, тут я не копенгаген) как минимум странно.
У меня есть ещё одно замечание, не описанные выше в комментариях. Связано оно именно с проектированием приложения.

При разработке ПО есть уровень проектирования, а есть уровень реализации.

На уровне проектирования находятся модели со своими связями и они должны быть предельно просто и понятно описаны:
User->cart->item->name
Catalog->item->price

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

После уровня проектирования идет уровень реализации, это то место где модели обретают связь с особенностями реализации сайта в выбранной вами платформе.
Так модель получает контроллер, шаблон и прочие классы завязанные на модель: UserController, UserValidator, UserForm и т.п.

Если вы будете на уровне проектирования использовать вспомогательный синтаксис сайта, особенно Yii, то описание вашей модели данных будет не универсальным и понятным лишь узкому кругу специалистов — программистам Yii, которых вы посвятили в свои правила.

>> они должны быть предельно просто и понятно описаны
При взгляде на примеры не понятно, что значит item — это «товар как модель каталога» или же «товар как модель корзины».
Я твёрдо считаю, что язык программирования отличается от разговорного языка.
Поэтому в нём должны быть более сухие и максимально чёткие обозначения.
Пусть они читаются не так лаконично, зато исключается всякая двусмысленность.

>> говорили на одном языке с руководством и исполнителями
Для таких разговоров, зачастую, упускаются незначительные детали, чтобы не перегружать слушателей не столь важными данными.
Например, вывод каталога с учётом остатков или отображение разных цен для разных типов клиентов.

Да и, если уж так, то более понятней для руководителя будет читать:
— Пользователь -> Корзина -> Товар -> Название
— Каталог -> Товар -> Цена

А как цена определяется, как высчитывается — это тема для отдельного разговора с отдельным описанием логики.

>> описание вашей модели данных будет не универсальным и понятным лишь узкому кругу специалистов — программистам Yii
А в чём заключается неуниверсальность?
Есть модель пользователя, есть модель корзины.
Какая бы ни была платформа для разработки, надо организовать эту связь.
То есть, в любом случае будет связь (relation), а каким образом (на уровне framework'а) она будет организована — это не имеет значения к наименованию связи.

К тому же, префиксы и постфиксы не взяты наобум.
Они, в принципе, нормально вписываются в общие правила именования.
Взять ту же модель — по аналогии с UserForm / UserValidator / UserController есть также класс UserModel.

>> которых вы посвятили в свои правила
Этот вопрос уже поднимался.
Как я думал, и как подчеркнули в комментариях — есть стандарты, которых придерживаются программисты.
И чтобы программист понимал, что и как именуется, его надо будет обучить (предоставить регламент или справку).
Пока я вижу некоторую проблему только в этом.
Пусть они читаются не так лаконично, зато исключается всякая двусмысленность.

Исключить двусмысленность можно грамотной проработкой моделей и изучением предметной области перед началом работы с кодом.

А в чём заключается неуниверсальность?


К примеру, если вы решите реализовать описанную моделями логику в виде объектно-ориентированной СУБД или, ещё проще, диаграммы классов, то постфикс Model будет избыточен.

Sign up to leave a comment.

Articles