Intereting Posts
Как получить день недели из временной метки Unix (PHP)? Вызов неопределенного метода Illuminate \ Database \ Query \ Builder :: associate () php. Должен ли я вызвать exit () после вызова заголовка Location:? Защитите от инъекций и правильного синтаксиса для метода $ _GET Cassandra + PHP + Thrift + извлекает плохую производительность нескольких строк Попытка вызова функции из пространства имен symfony Controller Скопируйте большие файлы (более 2 ГБ) в PHP Разбор огромных файлов XML в PHP Помогите! PHP, пытающийся передать FTPS, создает пустые файлы Magento – проверьте, если страница cms Artisan, создание таблиц в базе данных могут ли функции php использовать аргументы ключевых слов? (например, python) Получить стандартную локаль для языка в PHP Как обновить плагин wordpress за определенный промежуток времени, который я выбрал? Сохранение вывода openssl_random_pseudo_bytes в Postgres с использованием php? Я получаю сообщение об ошибке: неверная последовательность байтов для кодирования "UTF8"

Каким образом можно документировать файлы, классы и конструкторы?

Что является наиболее полезным / наиболее стандартным / наименее удивительным способом последовательного написания блоков комментариев для конструкторов и классов и файлов, содержащих только один класс?

  • Блоки комментариев для классов, а не конструкторы
  • Блоки комментариев для конструкторов, а не классов
  • Блоки комментариев для обоих конструкторов и классов -> В таком случае какие детали должны идти в каждом?

А потом сам файл? Для этого нужен блок комментариев, если он содержит только один класс? Какие детали должны идти туда?

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

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

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

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

Что вам абсолютно необходимо

Если вы хотите использовать PHPDoc, вам понадобится блок doc файла и другой блок doc после этого (как правило, блок doc класса).

Этим ** необходимо * иметь тег @package . Все остальное не является обязательным.

Я бы @package так далеко и сказал, что даже тег @package является необязательным, поскольку вы можете автоматически генерировать его для проекта. И если я правильно помню, PHPDoc позволяет даже установить пакет по умолчанию для всего, что не имеет тега.

Для документации в целом позвольте мне начать с примера ( более длинный пример в конце ):

Сколько раз вы можете объяснить, что означает «uri»:

Массивные документы Обратите внимание, что для getUri объясняется, что означает URI (просто нужно что-то обсудить в комментарии, который я предполагаю), в то время как это не в isAbsUri потому что вы можете хотя бы сказать «abs означает абсолютный» дважды.


Если вы не являетесь проектом с открытым исходным кодом (или необходимо отправить ПОЛНУЮ !!! 11eleven api documentation):

Я настоятельно рекомендую использовать правильные, длинные и описательные имена классов, переменных и методов вместо документации.

Нет никакой выгоды в написании чего-то снова в блоках док-станции, и поскольку это 2011 год, и у нас есть 120 терминалов с широким диапазоном символов и автозаполнение, просто нет необходимости больше сокращать все ради сохранения некоторых символов.

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

Хороший комментарий должен объяснить, ПОЧЕМУ что-то было сделано, в то время как код сам должен объяснить КАК, не требуя дальнейших комментариев.

Мой любимый пример для избыточных документов – это:

 class myClass { /** * Constructor */ public function __construct() { } 

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

Это не добавляет никакой ценности, но тратит время на чтение кода.

Пример правильного именования:

 class Person { /** * Set a persons weight in Kilogram * * @param float $kg Weight in Kilogram */ public function setWeight($kg) {} 

Этот код легко документировать, потому что вам нужно объяснить, что означает «кг», потому что некоторые люди могут использовать другую систему, и вы не можете использовать Google для «кг».

Я за то, чтобы писать

 class Person { /** * @param float $kilogram */ public function setWeight($kilogram) {} 

Блок doc лишний, потому что вызов setWeight на Person может ДЕЙСТВИТЕЛЬНО ожидать, чтобы установить Weight на Person. Не нужно снова писать это.

Использование $ kilogramm в качестве параметра также избавляет вас от необходимости объяснять его в документах, и я бы сказал, что в зависимости от вашей среды каждый может ожидать, что Google будет «килограммом», если он действительно не знает блок измерения.


Документация @PHPDoc

  • Конечно, мое скромное мнение
  • Если вы не используете подсказки типа, всегда используйте теги @param.
  • Всегда используйте теги @return
  • Не используйте теги @author. Собственность коллекционного кода более ценна, и информация всегда находится в репозитории управления версиями.
  • Используйте только теги @copyright, если вам нужно. Мне нравится только наличие файла LICENSE, но я не юрист, поэтому это может быть необходимо.

Встроенные комментарии:

 public function generateReport() { // get the db connection $reg = WhateverGlobalStorage::get(“db“); // auth if(!$reg->getOne("SELECT view_report FROM USER ...")) {} // template $id = $reg->getOne("select ... "); // render new ReportTemplate($id); // ... } 

Если это отдельные «блоки», просто переместите их на описательные именованные функции

 public function generateReport() { $this->checkAuthentication(); $template = this->createReportTemplate(); $this->renderReport($template); } // Not perfect but at least you can grasp what the method does much quicker 

Дополнительные ресурсы:

Слайды презентации, которые я дал на эту тему на некоторых конференциях: Slideshare: clean-code-stop-wasting-my-time

И еще маленький, немного более старый, разглагольствованный: they-told-you-to-document-everything-they-lied

Ссылки на книги:

Чистый код - обложка Clean Code: A Handbook of Agile Software Craftsmanship

Рефакторинг - обложка Рефакторинг: улучшение дизайна существующего кода

Более длинный пример

 abstract class xyzRequest { /** * Initializes this xyzRequest. * * Available options: * * * logging: Whether to enable logging or not (false by default) * * @param xyzEventDispatcher $dispatcher An xyzEventDispatcher instance * @param array $parameters An associative array of initialization parameters * @param array $attributes An associative array of initialization attributes * @param array $options An associative array of options * * @return bool true, if initialization completes successfully, otherwise false * * @throws <b>xyzInitializationException</b> If an error occurs while initializing this xyzRequest */ public function initialize(xyzEventDispatcher $dispatcher, $parameters = array(), $attributes = array(), $options = array()) { 

Давайте посмотрим, как выглядит эта документация. (Я шучу здесь немного, чтобы понять)

 * Initializes this xyzRequest. 

Итак, вызов -> инициализация на xyzRequest инициализирует этот запрос? В самом деле? Хорошо, если ты так говоришь!

  * Available options: * * * logging: Whether to enable logging or not (false by default) 

Нам сообщается о вариантах третьего параметра, а не о втором или третьем параметре, но, может быть, мы знаем это, если знаем структуру? (Так как мы не можем понять, что -> инициализировать, без того, чтобы кто-то говорил использовать, мы, возможно, не были такими умными …)

  * @param xyzEventDispatcher $dispatcher An xyzEventDispatcher instance 

Да, тип-подсказка есть. Поэтому, если метод ожидает «экземпляр xyzEventDispatcher», нам нужно передать «экземпляр xyzEventDispatcher». Хорошо знать.

  * @param array $parameters An associative array of initialization parameters * @param array $attributes An associative array of initialization attributes * @param array $options An associative array of options 

ОК. Так что это не линейный массив. Но мне нужно передать «параметры инициализации» методу «инициализации», который я мог бы вычислить.

Все еще не знаю, что мне действительно нужно пройти там, но до тех пор, как его документировано, это должно быть хорошо!

  * @return bool true, if initialization completes successfully, otherwise false 

Таким образом, логическое возвращаемое значение является «истинным» для «хорошего» и «ложного» для «плохого».

  * @throws <b>xyzInitializationException</b> If an error occurs while initializing this xyzRequest */ 

Итак, возникает исключение, если возникает ошибка, когда мы выполняем функцию, названную функцией?

Таким образом, исключения используются для ошибок. ОК. Хорошо знать.

  • Не говорит мне разницу между возвратом false и исключением.
  • @throws его самость прекрасно, потому что он добавляет информацию
  • Btw: Почему это BOLD, а не @link

Лично я комментирую только конструкторы, если есть что-то особенное, чтобы прокомментировать это (например, специальную инициализацию).

Я бы не сказал, что это «самый полезный» способ, но он сохраняет код аккуратным и повторяется два раза, то же самое не нужно (если это ваше внимание).

Комментировать все – файлы (авторство, авторское право, описание и т. Д.), Классы (описание, примеры кода), методы и свойства. Вот хороший пример с комментариями phpDoc .

Лично я считаю, что документация по классам и методам является самой важной документацией. Когда я пишу код, мне нужна помощь моей IDE, когда завершение кода показывает мне документацию, принадлежащую методу. Таким образом, я могу легко найти нужный мне метод.

Поскольку я стараюсь, чтобы явная инициализация классов была минимальной, я не комментирую конструктор пользователя. Следовательно, я стараюсь избегать использования самих конструкторов.

Код в методе или функции должен быть как можно более ясным, используя имена декларативных переменных и сохраняя их настолько малыми, насколько это возможно. Только когда я делаю что-то неожиданное, например, по вопросам интеграции, я их комментирую.