Хотите писать более чистый код? Используйте правило шести

Перевод статьи Want cleaner code? Use the rule of six автора David Amos.
Все хотят уметь писать чистый код. Про это даже написано множество книг!
Но Вам необязательно читать какую-либо книгу, чтобы научиться писать чистый код. Есть один трюк, которому может научиться каждый программист, чтобы его код казался менее запутанным.
Идея заключается в следующем:
Каждая строка кода делает только лишь одну вещь
Одна строка - одна задача.
Но только не сходите с ума.

Основная суть в том, что для чтения небольших строк кода требуется меньше усилий, чем для чтения длинных строк. Код, который легче читается - легче понимается. Теоретически, программы с более короткими строками кода легче поддерживать.
Но в тоже время небольшой код может быть также непонятным. (Вы когда нибудь видели APL?) И то, что вы можете разделить строку, не означает, что вы должны это делать.
В некоторых языках вы можете присвоить два значения двум переменным в одной строке:
x, y = 2, 7
Но также вы можете это сделать на разных строках кода:
x = 2
y = 7
Но серьезно, вам это реально нужно? Так вот - как узнать, нужно ли разделять строку кода?
И дело не только в длине строки
Фелиен Херманс открывает свою книгу «Мозг программиста» неоспоримой истиной: «Путаница — это часть программирования».

Книга Херманса (которую я очень рекомендую) объясняет, как три функции памяти вашего мозга работают вместе, чтобы понять код:
1) Долговременная память (LTM): хранит информацию для долгосрочного поиска, такую как ключевые слова, синтаксис и часто используемые идиомы и шаблоны.
2) Кратковременная память (STM): хранит новую информацию для краткосрочного извлечения (менее 30 секунд!), такую как имена переменных и специальные значения.
3) Рабочая память (Working Memory): обрабатывает информацию из LTM и STM, чтобы сделать выводы и получить новые знания.
Кратковременная и рабочая памяти не могут хранить много данных - только 4-6 вещей одновременно! Перегрузив их - получим рецепт путаницы.

Отсюда вытекает правило для определения того, является ли строка кода слишком сложной:
Правило шести: строку кода, содержащую более 6 фрагментов информации, следует упростить.
Пример кода на Python:
map(lambda x: x.split('=')[1], s.split('?')[1].split('&')[-3:])
Вам тяжело прочесть эту строку? Мне тоже. И на это есть веская причина.
Вам нужно знать, что такое map
, lambda
, и .split()
. Переменные x
и s
, строки =
, ?
и &
, индекс [1]
и срез [-3:]
занимают место в кратковременной и рабочей памяти мозга. И всего тут - 10 вещей! Мозг просто не успевает все это обработать и запомнить.
Или, может быть, ваш может.
Но если это так - у вас хороший опыт за плечами.
Ваш мозг читает синтаксис s.split('?')[1]
как часть строки справа от вопросительного знака. И вы можете реконструировать код, используя информацию, хранящуюся в вашей долговременной памяти. Но вы по-прежнему обрабатываете только несколько фрагментов за раз.
Итак… мы можем определить, когда строка кода является сложной. Что теперь?
Если код сбивает столку, разбейте его
То есть разбейте его на более мелкие части!
Есть две стратегии, которые я использую для разбивки кода. Я называю их SIMPLE и MORF.
Стратегия SIMPLE добавляет строки кода для снижения когнитивной нагрузки.

Давайте применим SIMPLE к той неприятной строчке, которую мы видели ранее. Удалите второй аргумент из map()
и поместите его в отдельную строку:
query_params = s.split('?')[1].split('&')[-3:]
map(lambda x: x.split('=')[1], query_params)
Это все еще может быть трудно читается. Так как в первой строке нужно отслеживать семь вещей:
query_params
s
.split()
'?'
[1]
'&'
[-3:]
Но в каждой строке меньше операций для отслеживания, чем раньше. Вашему мозгу это проще обработать.
Снова примените SIMPLE и переместите s.split('?')[1]
на новую строку:
url_query_string = s.split('?')[1]
query_params = url_query_string.split('&')[-3:]
map(lambda x: x.split('=')[1], query_params)
А теперь сравните это с оригинальным однострочником. Какой из них легче читать и понимать?
Стратегия MORF использует другой подход и группирует код в функции.

Вот как выглядит MORF применительно к нашему однострочнику:
def query_params(url):
return url.split('?')[1].split('&')[-3:]
map(lambda x: x.split('=')[1], query_params(s))
Вы даже можете комбинировать стратегии MORF и SIMPLE:
def query_params(url):
query_string = url.split('?')[1]
return query_string.split('&')[-3:]
map(lambda x: x.split('=')[1], query_params(s))
Вам не нужно понимать код, чтобы почувствовать эффект. Каждая строка легче обрабатывается вашим мозгом.
Есть и бонусная выгода!
Как только вы узнаете, что ваши кратковременная и рабочая памяти не перегружены, вы поймете, что любая оставшаяся путаница связана с отсутствием информации в вашей долговременной памяти.
Другими словами, стратегии SIMPLE и MORF не просто помогают вам писать более чистый код. Они помогут вам выявить пробелы в знаниях, которые вы сможете улучшить с практикой!
Задание
Посмотрите на код, который мы получили с помощью использования стратегии SIMPLE:
url_query_string = s.split('?')[1]
query_params = url_query_string.split('&')[-3:]
map(lambda x: x.split('=')[1], query_params)
В одной строке все еще содержится более шести «идей», и ее следует, согласно правилу шести, разделить:
- Какую строку нужно разделить?
- Какой идей здесь нужно воспользоваться?
- Как бы вы разделили эту строку?
- Разделение сильно изменило ситуацию?
Материал подготовлен с ❤️ редакцией Кухни IT.