Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Что вам нужно?

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

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

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

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

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

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


Если вы не являетесь проектом с открытым исходным кодом (или вам необходимо отправить документацию COMPLETE!!! 11eleven api):

Я бы сильно предлагал вместо правильный, длинный и описательный класс, имена переменных и методов.

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

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

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

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

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

Некоторые рекомендации говорят, что вы HAVE, чтобы документировать ВСЕ, и в итоге вы снова становитесь свидетелями очевидцев.

Это не добавляет значения, но тратит время при чтении кода.

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

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 on 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

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

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

Clean Code - CoverClean Code: A Handbook of Agile Software Craftsmanship

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

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

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

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

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

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

Таким образом, возвращаемое значение boolean является "true" для "good" и "false" для "bad".

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

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

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

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

Ответ 2

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

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

Ответ 3

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

Ответ 4

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

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

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