Effective Dart: Documentation Guide
Effective Dart: Documentation Guide

Привет, если вы на пути изучения Flutter/Dart или вам просто интересно почитать про путь изучения, подписывайтесь на мой канал в telegram, буду рад вас видеть! А сегодня поговорим про руководство по документации в Dart!

Содержимое:

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

Мы все знаем, что код должен быть самодокументируемым, и не все комментарии полезны. Но реальность такова, что большинство из нас пишут не так много комментариев, как следовало бы. Это как с физическими упражнениями: технически вы можете сделать слишком много, но гораздо более вероятно, что вы делаете слишком мало. Попробуйте делать это еще активнее.

Комментарии

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

DO составляйте комментарии как предложения

? хорошо

// Нет, если этому что-то предшествует.
if (_chunks.isNotEmpty) return false;

Первое слово пишется заглавной, если только оно не является идентификатором с учетом регистра. Заканчивайте комментарий точкой (или "!", или "?"). Это верно для всех комментариев: комментариев к документам, встроенных материалов, даже задач. Даже если это фрагмент предложения.

DON’T не используйте блокирующие комментарии для документации

? хорошо

void greet(String name) {
  // Предположим, у нас есть достоверное имя.
  print('Hi, $name!');
}

? плохо

void greet(String name) {
  /* Предположим, у нас есть достоверное имя. */
  print('Hi, $name!');
}

Вы можете использовать комментарий блока (/* ... */), чтобы временно закомментировать часть кода, но все остальные комментарии должны использовать //.

Комментарии к документу

Doc комментарии особенно удобны, потому что dart doc анализирует их и генерирует из них красивые страницы doc. Doc комментарий - это любой комментарий, который появляется перед объявлением и использует специальный синтаксис ///, который ищет dart doc.

DO используйте комментарии /// doc для элемента и типа документа

Правила Линтера: slash_for_doc_comments

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

? хорошо

/// Количество символов в этом фрагменте, когда он не разделен.
int get length => ...

? плохо

// Количество символов в этом фрагменте, когда он не разделен.
int get length => ...

По историческим причинам dart doc поддерживает два синтаксиса doc комментариев: /// ("стиль C#") и /** ... */ ("стиль JavaDoc").* Мы предпочитаем ///, потому что он более компактный. **А /** и */ добавляют две строки без содержимого к многострочному комментарию doc. Синтаксис /// также легче читается в некоторых ситуациях, например, когда doc комментарий содержит маркированный список, в котором для обозначения элементов списка используется *.

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

PREFER предпочтительно писать комментарии к документам для общедоступных API

Правила Линтера: package_api_docspublic_member_api_docs

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

CONSIDER подумайте о написании комментария к документу библиотечного уровня

В отличие от таких языков, как Java, где класс является единственной единицей организации программы, в Dart библиотека сама по себе является сущностью, с которой пользователи работают напрямую, импортируют и думают о ней. Это делает директиву library отличным местом для документации, знакомящей читателя с основными концепциями и функциональными возможностями, предоставляемыми внутри. Рассмотрите возможность подключения:

  • Краткое изложение того, для чего предназначена библиотека.

  • Пояснения к терминологии, используемой в библиотеке.

  • Пара полных примеров кода, описывающих использование API.

  • Ссылки на наиболее важные или наиболее часто используемые классы и функции.

  • Ссылки на внешние ссылки в домене, к которому относится библиотека.

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

? хорошо

/// Действительно отличная библиотека тестов.
@TestOn('browser')
library;

CONSIDER подумайте о написании комментариев к документам для частных API

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

DO начинайте комментарии к документу с краткого изложения в одном предложении

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

? хорошо

/// Удаляет файл из файловой системы по адресу [путь].
void delete(String path) {
  ...
}

? плохо

/// В зависимости от состояния файловой системы и разрешений пользователя
/// определенные операции могут быть возможны, а могут и не выполняться. Если по адресу
/// [путь] файла нет или доступ к нему невозможен, эта функция выдает либо [IOError]
/// или [PermissionError], соответственно. В противном случае файл будет удален.
void delete(String path) {
  ...
}

DO выделите первое предложение комментария к документу в отдельный абзац

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

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

? хорошо

/// Удаляет файл по [path].
///
/// Выдает ошибку [IOError], если файл не может быть найден. 
/// Выдает ошибку [PermissionError], если файл присутствует, но не может быть удален.
void delete(String path) {
  ...
}

? плохо

/// Удаляет файл по адресу [path]. Выдает ошибку [IOError], если файл не может быть найден. 
/// Выдает ошибку [PermissionError], если файл присутствует, 
/// но не может быть удален.
void delete(String path) {
  ...
}

AVOID избегайте избыточности в окружающем контексте

Читатель комментария к документу о классе может четко видеть название класса, какие интерфейсы он реализует и т.д. При чтении документации о member подпись находится прямо перед ним, а класс, который его содержит, очевиден. Ничего из этого не нужно указывать в комментарии к документу. Вместо этого сосредоточьтесь на объяснении того, чего читатель еще не знает.

? хорошо

class RadioButtonWidget extends Widget {
  /// Устанавливает для всплывающей подсказки значение [строки], которое должно было быть переведено в текст с использованием
  /// текущего шрифта.
  void tooltip(List<String> lines) {
    ...
  }
}

? плохо

class RadioButtonWidget extends Widget {
  /// Устанавливает всплывающую подсказку для этого виджета с переключателем в виде списка строк в
  /// [lines].
  void tooltip(List<String> lines) {
    ...
  }
}

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

PREFER предпочитайте начинать комментарии к функциям или методам с глаголов третьего лица

Комментарий к документу должен быть сосредоточен на том, что делает код.

? хорошо

/// Возвращает `true`, если каждый элемент удовлетворяет [predicate].
bool all(bool predicate(T element)) => ...

/// Запускает секундомер, если он еще не запущен.
void start() {
  ...
}

PREFER предпочитайте начинать комментарий к логической переменной или свойству с существительного

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

? хорошо

/// Текущий день недели, где `0` это Воскресенье.
int weekday;

/// Количество отмеченных кнопок на странице..
int get checkedCount => ...

PREFER предпочитайте начинать логическую переменную или комментарий к свойству с "Whether", за которым следует существительное или герундий

Комментарий к документу должен прояснить, какие состояния представляет эта переменная. Это верно даже для getter, которые могут выполнять вычисления или другую работу.

? хорошо

/// Отображается ли модель в данный момент для пользователя.
bool isVisible;

/// Должен ли модальный режим подтверждать намерение пользователя осуществлять навигацию.
bool get shouldConfirm => ...

/// Приведет ли изменение размера текущего окна браузера также к изменению размера модального окна.
bool get canResize => ...

Примечание

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

DON’T не пишите документацию как для getter, так и для setter свойства

Если у свойства есть как getter, так и setter, то создайте комментарий doc только для одного из них. dart doc обрабатывает getter и setter как одно поле, и если и у getter, и у setter есть комментарии doc, то dart doc отбрасывает комментарий doc у setter.

? хорошо

/// Уровень pH воды в бассейне.
///
/// Колеблется от 0 до 14, что соответствует уровню кислотности и щелочности, при этом 7 - нейтральный.
int get phLevel => ...
set phLevel(int level) => ...

? плохо

/// Глубина воды в бассейне, в метрах.
int get waterDepth => ...

/// Изменяет глубину воды в общей сложности [метров] в высоту.
set waterDepth(int meters) => ...

PREFER предпочитайте запускать библиотеку или вводить комментарии с существительными

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

? хорошо

/// Фрагмент неразрывного выходного текста, заканчивающийся твердым или мягким символом новой строки.
///
/// ...
class Chunk { ... }

CONSIDER рассмотрите возможность включения примеров кода в комментарии к документу

? хорошо

/// Возвращает меньшее из двух чисел.
///
/// ```dart
/// min(5, 3) == 3
/// ```
num min(num a, num b) => ...

Люди прекрасно умеют принимать информацию на примерах, поэтому даже один пример кода облегчает изучение API.

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

Правила Линтера: comment_references

Если вы заключаете такие элементы, как имена переменных, методов или типов, в квадратные скобки, то dart doc просматривает название и ссылки на соответствующие документы по API. Круглые скобки необязательны, но могут прояснить ситуацию, когда вы ссылаетесь на метод или конструктор.

? хорошо

/// Вызывается ошибка [StateError] если ...
/// похожий на [anotherMethod()], но ...

Чтобы создать ссылку на члена определенного класса, используйте название класса и имя члена, разделенные точкой:

? хорошо

/// Аналогично [Duration.inDays], но имеет дело с дробными днями.

Синтаксис dot также может использоваться для ссылки на именованные конструкторы. Для неназванного конструктора используйте .new после имени класса:

/// To create a point, call [Point.new] or use [Point.polar] to ...

DO используйте prose для объяснения параметров, возвращаемых значений и исключений

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

? плохо

/// Определяет флаг с заданным названием и аббревиатурой.
///
/// @param name Имя флага.
/// @param abbr Аббревиатура флага.
/// @returns Новый флаг.
/// @throws ArgumentError Если уже есть данное имя или аббреиатура.
Flag addFlag(String name, String abbr) => ...

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

? хорошо

/// Определение флага.
///
/// Выдает ошибку [ArgumentError], если уже существует параметр с именем [name] или
/// уже существует опция, использующая аббревиатуру [abbr]. Возвращает новый флаг.
Flag addFlag(String name, String abbr) => ...

DO размещайте комментарии doc перед аннотациями к метаданным

? хорошо

/// Кнопка, которую можно включать и выключать.
@Component(selector: 'toggle')
class ToggleComponent {}

? плохо

@Component(selector: 'toggle')
/// Кнопка, которую можно включать и выключать.
class ToggleComponent {}

Markdown

В комментариях к документу вы можете использовать большинство форматов markdown, и dart doc обработает их соответствующим образом с помощью пакета markdown.

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

/// Это абзац обычного текста.
///
/// В этом предложении есть *два* подчеркнутых слова (курсив) и 
/// **два** подчеркнутых слова (жирный шрифт).
///
/// Пустая строка создает отдельный абзац. В нем есть некоторый 
/// "встроенный код", разделенный обратными знаками.
///
/// * Неупорядоченные списки.
/// * Выглядят как маркированные списки в формате ASCII.
/// * Вы также можете использовать `-` или `+`.
///
/// 1. Пронумерованные списки.
/// 2. Они, ну, в общем, пронумерованы.
/// 1. Но ценности не имеют значения.
///
///     * Вы также можете вставлять списки.
///     * Они должны быть с отступом не менее 4 пробелов.
///     * (Ну, 5, включая пробел после `///`.)
///
/// Блоки кода огорожены тройными обратными метками:
///
/// ```dart
/// this.code
///     .will
///     .retain(its, formatting);
/// ```
///
/// В качестве языка программирования (для подсветки синтаксиса) по умолчанию используется Dart. Вы можете
/// указать его, указав название языка после начальных обратных символов:
///
/// ```html
/// <h1>HTML is magical!</h1>
/// ```
///
/// Ссылки могут быть:
///
/// * https://www.just-a-bare-url.com
/// * [with the URL inline](https://google.com)
/// * [or separated out][ref link]
///
/// [ref link]: https://google.com
///
/// # A Header
///
/// ## A subheader
///
/// ### A subsubheader
///
/// #### Если вам нужно так много уровней заголовков, вы делаете это неправильно

AVOID избегайте чрезмерного использования markdown

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

AVOID избегайте использования HTML для форматирования

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

PREFER предпочитайте обратные привязки к блокам кода

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

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

? хорошо

/// Ты можешь использовать [CodeBlockExample] вот так:
///
/// ```dart
/// var example = CodeBlockExample();
/// print(example.isItGreat); // "Yes."
/// ```

? плохо

/// Ты можешь использовать [CodeBlockExample] вот так:
///
///     var example = CodeBlockExample();
///     print(example.isItGreat); // "Yes."

Написание

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

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

PREFER предпочитайте краткость

Будьте ясны и точны, но в то же время немногословны.

AVOID избегайте сокращений, если они не бросаются в глаза

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

PREFER предпочитайте использовать "this" вместо "the" для ссылки на экземпляр элемента

При документировании элемента для класса вам часто приходится ссылаться на объект, для которого вызывается элемент. Использование "the" может быть неоднозначным.

class Box {
  /// The value this wraps.
  Object? _value;

  /// True if this box contains a value.
  bool get hasValue => _value != null;
}

Комментарии (2)


  1. Fancryer
    03.04.2024 19:41
    +1

    Если честно, перевод ужасен. Блокирующие комментарии? Твëрдый или мягкий символ новой строки? По-моему, даже Гугл переводчик справился бы лучше.


    1. tyukmaev_i Автор
      03.04.2024 19:41

      «Блокирющие комментарии» такое я не видел, возможно опечатка. Но в целом согласен перевод нужно подтянуть!