КРАТКИЙ КОНСПЕКТ книги
"Чистый код" Роберт Мартин

О книге:

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

Критерии хорошего кода:

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

Хороший код не только легко читается, но и легко меняется. Код который легко читается и код который легко меняется не одно и тоже.

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

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

Любой код рано или поздно загнивает. Чтобы этого не происходило следует соблюдать «правило бойскаута»: «оставь место стоянки чище, чем оно было до твоего прихода». Чистка не обязательно должна быть глобальной, достаточно почистить хотя бы небольшой кусок кода, режущий глаз.

Зачем чистить код, если он уже работает? Потому что по статистике соотношение чтения и написания кода более чем 10:1, так как для написания нового кода нужно постоянно читать старый. Не поленитесь почистить только что написанный и уже работающий код и при решении задач в следующий раз, вы скажете себе спасибо.

Имена переменных, методов и классов.

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

Выбирайте имена, так, чтобы они не в водили в заблуждение читателя кода. Если переменная называется accountList, читатель кода подсознательно считает что данная переменная хранит список. Если это не так, лучше назвать переменную просто accounts. По настоящему устрашающий пример дизинформации — использование в качестве имени переменной строчной L и прописной O, потому, что эти буквы почти не отличаются от констант 1 и 0.

Остерегайтесь мало заметных различий в именах.

Если имена различаются, то они должны обозначать разные понятия. Записывайте различающиеся имена так, чтобы читатель кода понимал, какой смысл заложен в этих различиях.

Используйте удобно произносимые слова. Это облегчает обсуждения среди программистов и позволяет новым программистам быстрее вникнуть в работу системы.

Выбирайте имена, удобные для поиска. Одно-двух буквенные имена сложно искать, так как поиск находит их в составе других имен. Длинна кода должна соответствовать размеру его области видимости.

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

Имена классов должны представлять из себя существительные или их сочетания, но никак не глаголы. Старайтесь не использовать в именах классов такие слова как Manager, Info, Data, Processor.

Имена методов должны быть глаголами и глагольными сочетаниями.

Выберите одно слово для представления одной абстрактной концепции и придерживайтесь его.

Используйте имена из пространства задачи и пространства решений (название паттернов и другая информация, которая о многом сможет сказать программисту).

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

Не добавляйте избыточный контекст. Не включайте в имя больше контекста чем необходимо.

Правила написания хороших функций и структура кода

Функция должна быть компактной, даже очень маленькой. Желательно чтобы длинна функции не превышала 20 строк.

Функции не должны содержать вложенных структур, так как это приводит к их увеличению и усложняет понимание работы функции.

Функция должна выполнять только одну операцию. Она должна выполнять ее хорошо, и ничего другого она делать не должна.

Следует избегать побочного эффекта, когда функция вносит изменения в переменные класса или глобальные переменные, если это не является той самой одной операцией, выполняемой функцией.

Под одной операцией понимается набор действий, находящихся на одном уровне абстракции.

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

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

Чтение кода сверху вниз: за каждой функцией должны следовать функции следующего уровня абстракции (вертикальное форматирование).

Каждая группа строк представляет законченную мысль. Эти мысли следует отделять друг от друга пустыми строками.

Концепции, тесно связанные друг с другом должна находится поблизости друг от друга по вертикали.

Команда switch допустима, если она встречается лишь раз в программе, используется для создания полиморфных объектов и скрывается за отношениями наследования, чтобы оставаться невидимой для остальных частей системы.

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

Наличие более двух аргументов функции усложняет написание тестов.

Если функция должна получать более двух параметров, вероятно имеет смысл упаковать некоторые из аргументов в отдельных класс, тем самым сократив количество передаваемых параметров.
Пример:
makeCircle (x, y, radius);
makeCirlce(center, radius);

Аргументы-флаги недопустимы. Передача логического значения функции говорит о том, что функция выполняет более одной операции.

Функция либо изменяет состояние объекта либо возвращает информацию о нем. Совмещение двух операций приводит к путанице.

Используйте исключения вместо возвращения кодов ошибок. Это позволит упростить и изолировать код обработки ошибок от ветви нормального выполнения.

Тела блоков try и catch рекомендуется выделять в отдельные функции. Обработка ошибок — это одна операция. Значит функция обрабатывающая ошибки ничего другого делать не должна.

Не возвращайте и не передавайте в вызове функции значение null. Это заставляет делать дополнительные проверки в вызывающем коде. Вместо null лучше вернуть исключение либо объект паттерна «особый случай».

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

Объекты предоставляют поведение и скрывают данные. Структуры предоставляют данные но лишены сколько нибудь значимого поведения.

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

Если нужна гибкость в расширении поведения, то лучше использовать типы данных и процедуры. Объектно-ориентированный код усложняет добавление новых функций, так как для этого должны изменится все классы.

Правильные комментарии и тесты

Не комментируйте плохой код — перепишете его.

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

Если вы работаете в команде, то следует выработать единые стандарты форматирования.

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

Тестовый код не менее важен, чем код продукта. Тесты на скорую руку равносильны отсутствию тестов. Если тестовый код сильно запутан, то написать новый код продукта займет меньше времени, чем попытки втиснуть новые тесты в обновленный пакет.

Количество директив asset должно быть минимальным. В тестовой функции должна проверяться только одна концепция.

Чистые тесты должны обладать пятью характеристиками, название которых образует FIRST:
быстрота (fast)
независимость (independent)
повторяемость (repeatable)
очевидность (self-validating)
своевременность (timely)

Правила написания хороших классов

Классы должны быть компактными.

Размер функций определяется количеством физических строк. Размер класса — количеством ответственности.

Имя класса должно описывать его ответственности.

Короткое описание класса должно укладываться примерно в 25 слов без всяких конструкций типа «если», «и», «или», «но».

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

Чем выше связность — тем лучше класс. Если классы утрачивают связность — разбейте их.

Класс должен зависеть от абстракций, а не от конкретных подробностей.

Архитектура проекта:

Три критерия простой архитектуры: устранение дубликатов, обеспечение выразительности и минимизация количества классов и методов.

Конструирование и использование системы — два разных процесса. Поэтому необходимо разделение инициализации объектов от логики работы с объектами. Подробнее об разделение ответственности и внедрении зависимостей читайте в главе 11 «Системы».

В качестве справочника и напоминания основных концепций чистого кода можно просмотреть 17 главу «Запахи и эвристические правила».

Копирование материалов разрешено при наличии активной ссылки на источник
Яндекс.Метрика