Читаемый код или программирование как искусство. Заключение

Заканчиваем читать «Читаемый код или программирование как искусство». В прошлый раз мы обсудили 5–7 главы: комментарии, циклы и условия. Сегодня обсудим 8–13 главы и подведём итог.

Глава 8. Разбивать длинные выражения на мелкие

Кратко:

  • Используйте объясняющие переменные;
  • Разбивайте условия по законам Де-Моргана;
  • Старайтесь найти решение изящнее.

Если выражение непонятное, объясните его через название переменной. Правило при выборе имени для такого выражения — ответ на вопрос, «что оно делает» или «что оно из себя представляет»:

username = line.split(':')[0].strip()
if username == "root":
...
Длинные условные конструкции упрощайте через преобразования:
// not (a or b or c) ⇔ (not a) and (not b) and (not c)
// not (a and b and c) ⇔ (not a) or (not b) or (not c)

// тогда такую строку:
if (!(file_exists && !is_protected)) ...

// можно переписать так:
if (!file_exists || is_protected) ...

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

Глава 9. Убирайте лишние переменные

Кратко:

  • Ранний выход лучше временной переменной;
  • Маленькая область видимости лучше, чем большая;
  • Константы лучше переменных.

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

now = datetime.now()
root_message.last_view_time = now
// datetime.now() — понятно без объясняющей переменной
// можно переписать так:
root_message.last_view_time = datetime.now()

Промежуточную переменную, которая хранит в себе результат, можно заменить ранним выходом из функции. Правило — «Завершите задачу как можно раньше»:

var remove_one = function (array, value_to_remove) {
  var index_to_remove = null;
  for (var i = 0; i < array.length; i += 1) {
    if (array[i] === value_to_remove) {
      index_to_remove = i;
      break;
    }
  }

  if (index_to_remove !== null) {
    array.splice(index_to_remove, 1);
  }
};

// можно переписать так:
var remove_one = function (array, value_to_remove) {
  for (var i = 0; i < array.length; i += 1) {
    if (array[i] === value_to_remove) {
      array.splice(i, 1);
      return;
    }
  }
};

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

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

Главы 10–11. Одна задача за раз

Кратко:

  • Выделяйте подзадачи из основной задачи;
  • Пишите как можно меньше кода, «заточенного под проект»;
  • Упрощайте интерфейсы;
  • Выполняйте одну задачу за раз.

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

Старайтесь писать как можно меньше кода, «заточенного под проект». Чем больше будет «общего» кода, тем он будет более переиспользуемым.

Пишите обёртки для работы с неудобными интерфейсами: для чтения куков, работы с локальным хранилищем, чтением файлов и т.д.

Главы 12–13. Пишите как можно меньше кода

Кратко:

  • Объясняйте логику проще;
  • Выясните, что уже реализовано в используемой библиотеке;
  • Сохраняйте кодовую базу компактной.

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

Изучите возможности библиотек и фреймворков, с которыми работаете. Возможно, какая-то функциональность уже реализована за вас.

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

  • Пишите больше «общего» кода;
  • Убирайте неиспользуемый и устаревший код;
  • Разбивайте проект на подпроекты.

Итог

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

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

Предыдущие части

  • Первая — названия переменных и функций, их двусмысленность, эстетика кода и простота;
  • Вторая — комментарии, циклы и условия.