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

Коменты‑зарубки TODO и FIXME

Зарубками помечают техдолг — то что надо сделать или починить, но сейчас не до того.

// TODO: унифицировать все модалы в единый класс
// FIXME: долго грузится в Сафари
// todo. needs refactoring
// FIXME!!!!!!! 

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

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

Как найти время для работы с техдолгом — в совете Фёдора Борщёва.

Документирующие коменты

Документирующие коменты подробно объясняют код, описывают функции, аргументы, содержат примеры использования. Это полезно для библиотек, сервисов, АПИ — интерфейсов, с которыми будут работать другие люди. Документация ускорит работу, упростит интеграцию, поможет избежать ошибок.

/**
 * Creates an object composed of keys generated from the results of running
 * each element of `collection` thru `iteratee`. The corresponding value of
 * each key is the number of times the key was returned by `iteratee`. The
 * iteratee is invoked with one argument: (value).
 *
 * @static
 * @memberOf _
 * @since 0.5.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
 * @returns {Object} Returns the composed aggregate object.
 * @example
 *
 * _.countBy([6.1, 4.2, 6.3], Math.floor);
 * // => { '4': 1, '6': 2 }
 *
 * // The `_.property` iteratee shorthand.
 * _.countBy(['one', 'two', 'three'], 'length');
 * // => { '3': 2, '5': 1 }
 */
var countBy = createAggregator(function(result, value, key) {
  if (hasOwnProperty.call(result, key)) {
    ++result[key];
  } else {
    baseAssignValue(result, key, 1);
  }
});

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

Документация не отменяет необходимость следить за качеством кода, покрытием тестами, обменом знаниями в команде и другими хорошими программистскими практиками

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

Документация не отменяет необходимость следить за качеством кода, покрытием тестами, обменом знаниями в команде и другими хорошими программистскими практиками

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

/**
* Документация для класса ProductCard
* Этот класс описывает карточку товара, принимает объект типа ProductData и HTMLElement куда рендерить карточку. TODO: добавить отслеживание карточки для аналитики
* Например, new ProductCard(productData, document.querySelector('.js-catalog'))
*
* @param {ProductData} данные карточки товара
* @param {HTMLElement} элемент родитель куда зарендерить
* 
* by leonidovich | 18.08.2016 via WebStorm
*/
class ProductCard {
  constructor(product, parent) {
    this.product = product
    this.root = parent
  }
        ​
  /**
  * Функция рендера. Создаёт HTMLElement по шаблону с обработчиками событий и затем добавляет его в родителя карточки, переданного в конструктор
  * Не требует передачи аргументов
  *
  * @returns {HTMLElement}
  */
  render() {
    const templateData = {
      product: this.product,
      onAddToCart: this.addToCard.bind(this),
      onRemoveFromCart: this.removeFromCart.bind(this),
    }
    const HTML = useTemplate('./product-card.html', templateData)
    return this.root.appendChild(HTML)
  }
        ​
  /**
  * Добавление в корзину
  * Метод добавляет товар в корзину через сервис, передаёт туда данные карточки. Если товар уже добавлен, тогда ничего не произойдёт
  *
  * @returns {Promise}
  */
  addToCard() {
    return basketService.addToCart(this.product)
  }
        ​
  /**
  * Удаление из корзины
  * Удаляет товар из корзины через сервис, возвращает промис
  *
  * @returns {Promise}
  */
  removeFromCart() {
    return basketService.removeFromCart(this.product)
  }
}

P. S. Это был совет о веб‑разработке. Хотите знать всё о коде, тестах, фронтенд‑разработке, цеэсэсе, яваскрипте, рельсах и джейде? Присылайте вопросы.

Веб‑разработка
Отправить
Поделиться
Запинить

Рекомендуем другие советы