Object Calisthenics by Jeff Bay - 9 простых правил для clean code
По наводке Сергея Бобровского прочитал презентацию Jeff Bay о практике Object Calisthenics. Практика представляет собой 9 простых правил по оформлению кода, что, как ни странно, позволяет (заставляет на самом деле :) ) писать более совершенный код (более лёгкий для понимания и поддержки).

1. Один уровень отступа для каждого метода
Условно если в методе есть цикл, то внутри него с натяжкой может быть if, но внутри этого if уже точно нет вложений второго уровня. Никаких циклов в цикле, никаких деревьев из if-ов. Решается активным использованием методов функционального программирования
2. Не используйте конструкцию ELSE (ELIF)
Внутри функции конструкцию типа
if a % 3 == 0:
return a
else:
return a + 1
легко заменить на
if a % 3 == 0:
return a
return a + 1
3. Оборачивайте все примитивы и строки в пользовательские классы
Если у вас есть переменная типа int, где хранится значение возраста - вы можете по ошибке передать туда отрицательное значение или сделать ещё что-то, что позволительно делать с целыми числами, но нельзя делать с возрастом. А вот если у вас есть собственный класс для хранения возраста с конкретным списком методов, которые позволительны для этого класса - вероятность ошибки резко снижается.
4. Оборачивайте стандартные структуры данных в пользовательские классы
Аналогично предыдущему пункту, но для списков, словарей, кортежей и прочих стандартных структур данных. По умолчанию они имеют очень много методов, плюс поддерживают изменение через прямую адресацию. Обернув их пользовательским классом - мы сводим к минимуму список допустимых операций, а значит и вероятность ошибки.
5. В одной строке кода не более одной “точки” (префикса вызова метода)
Не должно быть конструкций вида:
obj1.get_obj2().obj2method().get_obj3().obj3method()
где по ходу из одного объекта создается другой и выполняются уже его методы. Это создаёт избыточную связанность кода, плюс в принципе такие цепочки сложно отлаживать. При этом нет запрета на конструкции вида:
full_name = full_name_in.strip()
.lower()
.split()
где новый объект не создаётся, а последовательно применяются методы одного и того же объекта. Тем не менее правило “одна точка на строку” должно соблюдаться и в этом случае.
6. Не используйте аббревиатуры для названий классов и методов
Названия должны состоять из 1-2 слов и не должны дублировать контекст. Это заставляет лучше продумывать, что делает объект, не делать его мульти-комбайном.
7. Сохраняйте все сущности маленькими
Класс не должен превышать 50 строк, пакет не должен быть больше 10 файлов. Позволяет удерживать структуру объекта в голове во время отладки.
8. Не больше двух переменных в классе
Тоже направлено на минимизацию кода в классе, на то, чтобы структура была максимально продумана и разбита на простые части.
9. В классе не должно быть геттеров/сеттеров, все поля должны быть инкапсулированы
Если надо изменить поле класса - не должно быть возможности сделать это простым заданием значения. Условно, если для объекта Самолёт надо задать скорость ноль, это нельзя сделать просто написав
plane.speed = 0
Правильный вариант - выполнить метод Приземлить, в процессе которого скорость обнулится
plane.land()
Может позже распишу некоторые из этих пунктов отдельными заметками. А пока, хочу найти статистический анализатор кода для vs code, где можно задать эти правила. Правда, я не пишу большие проекты, где применение этих правил даст заметный выигрыш (понятно, что если надо написать двадцать-тридцать строчек кода применение этих правил и даже использование ООП скорее всего будет избыточно), но для тренировки мозгов - это будет интересно