Движемся по следующим главам "Чистого кода" Роберта Мартина, которых на сегодня выпало сразу три. Ниже вы сможете прочитать краткие тезисы по каждой главе и разбор на небольшом примере. С конспектом прошлых глав можно ознакомиться в предыдущих постах.
Форматирование кода
- Даже достаточно серьезные системы (объемом ~50 000 строк) можно собрать из небольших файлов, длинной 200-500 строк.
- Внутри каждого модуля, желательно придерживаться следующей структуры: верхние блоки содержат самые высокоуровневые структуры и алгоритмы, сложность которых постепенно снижается к низу. Внизу расположены самые детализированные и упрощенные функции низшего уровня.
- Переменные стоит объявлять как можно ближе к месту, в котором они используются. Переменные класса напротив стоит собрать в одном месте и помещать либо вверху класса либо внизу.
- Вертикальное форматирование. Тесно связанные концепции, должны следовать друг за другом. Если позволяет язык, то вызывающие функции лучше располагать над вызываемыми. Используйте пустые строки, чтобы сжать или разделить код, выделив связи.
- Горизонтальное форматирование. Следует избегать слишком длинных строк (длиннее ~120 символов). Отступы, как и пробелы хорошо помогают выделить подчиненность блоков и сделать код более читаемым. (супер, что часть этих тезисов и так закреплена в Python)
- При работе в группе крайне важно разработать и следовать правилам форматирования кода каждому из разработчиков.
Объекты и структуры данных
- Объекты данных предоставляют поведение и скрывают свои данные. Это позволяет легко добавлять новые виды объектов, не изменяя существующего поведения, но усложняет добавление нового поведения к объектам.
- Структуры поставляют данные, но не обладают значимым поведением. Это позволяет легко добавлять новые функции без изменения существующих структур, но усложняет добавление структур. Идеальный вариант - структура данных, содержащая открытые переменные без функций. Но он встречается крайне редко.
- Хороший программист относится без предубеждения к концепциям и выбирает ту, которая больше всего подходит к ситуации. Гибриды между структурами данных и объектами - вещь, которая чаще всего вызвана непониманием задачи.
В книге был приведен следующий пример:
При структурном программировании: есть несколько структур данных (круг, квадрат, треугольник), содержащие в себе информацию о длинах сторон(или радиус) и класс Geometry, содержащий метод, который вычисляет площадь этих фигур в зависимости от типа, один на всех. При необходимости добавить метод расчета периметра можно это легко сделать не изменяя отдельно структуры данных. Но, если нам необходимо добавить новый тип фигуры (например параллелограмм), то следом придется переработать все методы, взаимодействующие с этими структурами данных.
При применении ОО, у нас есть несколько объектов (круг, квадрат, треугольник), у каждого из которых есть свой метод, определяющий их площадь. Теперь становится легко добавить новую фигуру-объект, но если нам нужен будет добавить метод, вычисляющий периметр, придется отдельно занести его в каждый объект, созданный ранее.
Обработка ошибок
- Начиная работать над блоком исключений, сразу определите, что должен ожидать пользователь в любом случае, не зависимо от происходящего в блоке Try
- При работе с исключениями очень важно передавать достаточно контекста. Создавайте содержательные сообщения, из которых сразу понятно, в какой части программы совершена ошибка.
- Хорошая практика - группировать методы, собирающие исключения в классы. Определять, какой контекст должен объединять методы, следует исходя из задачи конкретного модуля/программы
- Хорошая практика - создавать методы-обертки для вызовов сторонних API. Это позволит легче перейти на новое API и помогает имитировать вызовы для тестирования.
- Обычно обработку ошибок и бизнес-логику следует разделять, но в некоторых ситуациях следует использовать обработку исключений для реализации паттерна ОСОБЫЙ СЛУЧАЙ. В таком случае в исключения заносятся и закрываются в отдельных объектах сбои в клиентской логике.
- Не стоит возвращать или передавать Null. Это вызывает ошибки и провоцирует загрязнение кода многочисленными проверками на его выявление. Эти проверки в конечном случае все равно не спасают ситуацию.
Для примера взял скрипт из прошлого поста и немного переработал его, чтобы отразить основные тезисы прочитанных глав. Код полностью также можно посмотреть здесь. Есть понимание, что следование всем правилам при столь малых задачах скорее раздувает код заставляет переполнять его сущностями. От этого ухудшается общая читаемость. Прошу отнестись к коду ниже, как к гипотетическому примеру, а не готовой программе на продажу)
3 главы за раз достаточно сложно уместить в формат постов тезисы-пример, поэтому в дальнейшем постараюсь брать 1-2 главы, чтобы можно было разобрать основные идеи и сократить длину текста.