Читаем Чистый код. Создание, анализ и рефакторинг полностью

Ничто так не раздражает, как висящий в конце вызова функции аргумент false. Зачем он здесь? Что изменится, если этот аргумент будет равен true? Смысл селектора трудно запомнить, но дело не только в этом — селектор указывает на объединение нескольких функций в одну. Аргументы-селекторы помогают ленивому программисту избежать разбиения большой функции на несколько меньших. Пример:

public int calculateWeeklyPay(boolean overtime) {

  int tenthRate = getTenthRate();

  int tenthsWorked = getTenthsWorked();

  int straightTime = Math.min(400, tenthsWorked);

  int overTime = Math.max(0, tenthsWorked - straightTime);

  int straightPay = straightTime * tenthRate;

  double overtimeRate = overtime ? 1.5 : 1.0 * tenthRate;

  int overtimePay = (int)Math.round(overTime*overtimeRate);

  return straightPay + overtimePay;

}

Функция вызывается с аргументом true при оплате сверхурочной работы по полуторному тарифу или с аргументом false при оплате по стандартному тарифу. Каждый раз, когда вы встречаете вызов calculateWeeklyPay(false), вам приходится вспоминать, что он означает, и это само по себе неприятно. Но по-настоящему плохо то, что автор поленился использовать решение следующего вида:

public int straightPay() {

  return getTenthsWorked() * getTenthRate();

}

public int overTimePay() {

  int overTimeTenths = Math.max(0, getTenthsWorked() - 400);

  int overTimePay = overTimeBonus(overTimeTenths);

  return straightPay() + overTimePay;

}

private int overTimeBonus(int overTimeTenths) {

  double bonus = 0.5 * getTenthRate() * overTimeTenths;

  return (int) Math.round(bonus);

}

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

<p>G16: Непонятные намерения</p>

Код должен быть как можно более выразительным. Слишком длинные выражения, венгерская запись, «волшебные числа» — все это скрывает намерения автора. Например, приводившаяся ранее функция overTimePay могла бы выглядеть и так:

public int m_otCalc() {

  return iThsWkd * iThsRte +

    (int) Math.round(0.5 * iThsRte *

      Math.max(0, iThsWkd - 400)

    );

}

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

<p>G17: Неверное размещение</p>

Одно из самых важных решений, принимаемых разработчиком, — выбор места для размещения кода. Например, где следует объявить константу PI? В классе Math? А может, ей место в классе Trigonometry? Или в классе Circle?

В игру вступает принцип наименьшего удивления. Код следует размещать там, где читатель ожидает его увидеть. Константа PI должна находиться там, где объявляются тригонометрические функции. Константа OVERTIME_RATE объявляется в классе HourlyPayCalculator.

Иногда мы пытаемся «творчески» подойти к размещению функциональности. Мы размещаем ее в месте, удобном для нас, но это не всегда выглядит естественно для читателя кода. Предположим, потребовалось напечатать отчет с общим количеством отработанных часов. Мы можем просуммировать часы в коде, печатающем отчет, или же накапливать сумму в коде обработки учетных карточек рабочего времени.

Чтобы принять решение, можно посмотреть на имена функций. Допустим, в модуле отчетов присутствует функция с именем getTotalHours, а в модуле обработки учетных карточек присутствует функция saveTimeCard. Какая из этих двух функций, если судить по имени, наводит на мысль о вычислении суммы? Ответ очевиден.

Очевидно, по соображениям производительности сумму правильнее вычислять при обработке карточек, а не при печати отчета. Все верно, но этот факт должен быть отражен в именах функций. Например, в модуле обработки учетных карточек должна присутствовать функция computeRunningTotalOfHours.

<p>G18: Неуместные статические методы</p>
Перейти на страницу:

Все книги серии Библиотека программиста

Программист-фанатик
Программист-фанатик

В этой книге вы не найдете описания конкретных технологий, алгоритмов и языков программирования — ценность ее не в этом. Она представляет собой сборник практических советов и рекомендаций, касающихся ситуаций, с которыми порой сталкивается любой разработчик: отсутствие мотивации, выбор приоритетов, психология программирования, отношения с руководством и коллегами и многие другие. Подобные знания обычно приходят лишь в результате многолетнего опыта реальной работы. По большому счету перед вами — ярко и увлекательно написанное руководство, которое поможет быстро сделать карьеру в индустрии разработки ПО любому, кто поставил себе такую цель. Конечно, опытные программисты могут найти некоторые идеи автора достаточно очевидными, но и для таких найдутся темы, которые позволят пересмотреть устоявшиеся взгляды и выйти на новый уровень мастерства. Для тех же, кто только в самом начале своего пути как разработчика, чтение данной книги, несомненно, откроет широчайшие перспективы. Издательство выражает благодарность Шувалову А. В. и Курышеву А. И. за помощь в работе над книгой.

Чед Фаулер

Программирование, программы, базы данных / Программирование / Книги по IT

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных