Книги - Чистый Код. Создание, анализ и рефакторинг (Роберт Мартин)

2013-03-30
Книги

Книги - Чистый Код. Создание, анализ и рефакторинг (Роберт Мартин) На днях закончил читать книгу Роберта Мартина - Чистый Код. В основном в ней идет речь про ООП программирование, про то как правильно организовывать программный код в классы, методы и функции, что бы его можно было легко поддерживать. Примеры кода приводятся на языке Java, но сама идея применима к разным языкам программирования. Каждый найдет в этой книге что то полезное для применения в своей работе. Далее некоторые идеи, которые мне больше всего понравились.

Классы, методы и функции

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

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

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

Структура кода

Поэтапное проектирование структуры, цитата из книги:

Когда я пишу свои функции, они получаются длинными и сложными. В них встречаются многоуровневые отступы и вложенные циклы. Они имеют длинные списки аргументов. Имена выбираются хаотично, а в коде присутствуют дубликаты. Но у меня также имеется пакет модульных тестов для всех этих неуклюжих строк до последней.

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

В конечном итоге у меня остаются функции, построенные по правилам. Я не записываю их так с самого начала. И вообще не думаю, что кому-нибудь это под силу.

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

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

Локальные переменные должны объявляться непосредственно перед первым использованием. Приватные функции должны определятся сразу же после первого использования. Вертикальное расстояние между вызовами и определениями должно быть минимальным.

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

Рефакторинг

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

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

Автоматическое тестирование кода

Тесты помогают убедится в работоспособности кода при его рефакторинге.

Тесты не должны зависеть друг от друга.

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

Многопоточный код

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

Удобочитаемость кода

Заменяйте "волшебные числа" именованными константами.

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

Код должен быть выразительным и разбитым на классы и методы. Даже если от этого он будет длиннее компактного но не понятного кода.

Комментарии

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

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

/**
* Порт, на котором будет работать fitnesse. По умолчанию 8082.
*
* @param fitnessePort
*/
public void setFitnessePort(int fitnessePort)
{
    this.fitnessePort = fitnessePort;
}

Всем, кто хочет научится писать правильно структурированный код, советую прочитать эту книгу. Удачи в самообразовании!