- Название: “Чистый дизайн. Практика эмпирического проектирования ПО” (Tidy First? A Personal Exercise in Empirical Software Design)
- Автор: Кент Бек (Kent Beck)
- Начало чтения: 11.01.25
- Конец чтения: 16.01.25
- Чистое время чтения: 4 часа
- Оценка: 3/5
- Откуда узнал про книгу: наткнулся на неё в Доме книги “Молодая Гвардия”. Зацепила названием, обложкой и описанием
- Цель на проработку книги: повысить качество кода, который я пишу и систем, которые создаю
- Задачи:
- Изучить и законспектировать советы, практики и подходы
- Применять их на практике
Рецензия 
Название в русском переводе не соответствует содержанию. Это не книга о дизайне программного кода. В ней рассматривается только один из аспектов дизайна — очистка (рефакторинг на минималках). Ожидал от книги большего.
Что понравилось:
- Советы из первой части весьма интересны и полезны. Некоторые не встречал в других книгах, до некоторых дошел сам
- Книга совсем небольшая. Если бы воды было больше, потраченного времени было бы жаль ещё сильнее
- Понял, что такое опцион
Что не понравилось:
- Половину всей книги занимают фразы типа “А вот про это я расскажу в следующей своей книге”
- Кривой перевод на русский. Начиная с названия, заканчивая самим текстом. “Сhanging from an integer to a long” переведено как “переход от целого к длинному целому”. В контексте смены типа, используемого для описания свойства объекта, гораздо понятнее было бы “переход от int к long int”
- Весьма спорные тезисы про стоимость ПО
- Недостаточно раскрыта тема сцепления и связности
- Мало практических примеров. Их вообще почти нет
- Постоянно упоминаются средства рефакторинга современных IDE. Складывается ощущение, что автор не умеет программировать без них
- Запутанность. Несмотря на разделение по главам, автор не всегда придерживается её. Книга местами выглядит как набор рандомно разбросанных тезисов, а не цельный рассказ
Конспект 
Дизайн ПО 
Необходимо научиться проектировать так, чтобы это приносило пользу повседневной работе.
“Когда проектировать дизайн?” Эмпирический подход отвечает: “По обстоятельствам. Тогда, когда от этого будет профит”.
Код растёт органично. Невозможно сразу написать весь код, который когда-либо понадобится.
Методы очистки 
Методы очистки — это подмножество методов рефакторинга.
Убирать излишнюю вариативность 
Если есть несколько способов сделать одно и то же, нужно выбрать один способ и придерживаться его во всем коде. Увидев разные конструкции, читатель кода будет думать, что они делают разные вещи, хотя на самом деле делают одно и то же — это породит путаницу. Излишнюю вариативность нужно удалять
Начинать с конца 
Иногда может быть полезно посмотреть под другим углом.
- Начинать написание функции с последней строчки. Как будто уже есть все результаты
- Сначала писать тест, который должен проходить
- Сначала проектировать функции-хелперы
Располагать код в порядке, удобном читателю 
Пояснительные переменные 
Не нужно бояться разбивать большие выражения на части и выносить их в отдельные переменные. Даже если вы не писали само выражение, а просто разбираетесь в чужом кода. Это упростит дальнейший анализ и понимание и вам самим и будущим читателям.
Явная передача параметров 
Если есть блок кода, в котором данные между различными частями передаются неявно, лучше разделить его на две части. В одной явно собирать все данные, в другой — использовать.
Визуальная группировка инструкций 
Если при чтении блока кода возникают мысли “Эта часть делает это, а эта часть - то”, то как минимум нужно вставить между этими частями пустую строку.
Одна большая свалка 
Иногда из-за слишком большого разбиения на маленькие блоки код становится читать ещё труднее. В этом случае нужно объединить его, а потом заново побить на блоки, но более осмысленно.
Комментарии 
- Важно записывать в комментарии то, что вы поняли со словами “Аа, вот, что тут происходит”
- В комментах нужно отвечать на вопросы, которые могут возникнуть у читателя
- Можно оставлять комментарий в начале файла о предназначении этого файла
- Лучше помечать слабые моменты
// TODO
, чем забывать о них
Интеграция очистки в рабочий процесс 
Размер очистки 
Нужно выполнять только тот объем очистки, который удовлетворит неотложные потребности.
Очистка порождает очистку. Нужно понимать, когда стоит остановиться. Неудачная очистка дороже нескольких удачных.
Очистка должна занимать минуты; максимум — час. Если больше — вы что-то делаете не так.
Когда проводить очистку? 
Очистку не нужно планировать и выделять в отдельную задачу. Если нужно изменить грязный код, перед изменением его нужно очистить.
Никогда 
- Если код никогда не будет меняться. “Не сломано — не чини”.
- Если изменения не дадут никакой полезной информации
Позже 
- Если предполагает много работы
- Если окупится позже
Главная мысль, которую я понял про рефакторинг по своему опыту: “Потом” в 99% случаев равно “никогда”.
После изменения функциональности 
- Если скоро будут вноситься изменения в ту же область кода
- Если она дешевле, чем очистка “до”
- Если затраты времени на очистку сопоставимы с затратами на изменение поведения
- Если очистить после добавления будет проще, чем очистить перед следующим добавлением
До изменения функциональности 
- Если очистка даст немедленный эффект
- Если вы точно знаете, что и как нужно делать
- Если стоимость очистки + стоимость изменения поведения после очистки" меньше, чем “стоимость изменения поведения без очисти”
Распутывание сложных систем 
Если вы просидели час, в ходе которого итеративно изменяли поведение, чистили код и писали новые тесты, то есть 3 варианта, что со всем этим делать:
- Закоммитить всё как есть в один PR
- Разделить очистку и изменения по разным PR или коммитам в одном PR
- Удалить все сделанное и начать заново, выделив очистку в начало
Рекомендуется выбрать третий вариант. В ходе повторной реализации можно заметить что-то новое для себя.
Теория 
Структура системы 
Структура системы — это:
- Иерархия элементов
- Отношения между элементами
- Выгода, обусловленная этими отношениями
Структура системы не влияет на её поведение. Она упрощает или усложняет добавление новых вариантов.
Невозможно точно определить, достаточно ли усилий вложено в правильную организацию структуры.
Задача системного дизайна — согласовать императивы “зарабатывать раньше, тратить позже” и “создавать вариативность, а не однозначность”.
Ценность 
Ценность программного кода в:
- Том, что он делает сегодня
- Том, какие новые возможности в него можно будет добавить завтра
Чем больше вариативность (=функциональность) системы, тем больше её ценность. Нужно стремиться к тому, чтобы не было препятствий для вариативности. Рост накладных расходов на внесение изменений мешает вариативности.
Обратимость 
Очистка перед изменением обратима. Если она была неудачна, её можно отменить. Если мы неудачно изменили поведение, изменить его может быть гораздо сложнее.
Нужно максимально тщательно проводить ревью необратимых решений.
Когда изменения дизайна могут быть необратимыми или трудно обратимыми:
- Выделение кода в отдельный сервис
- Распространение решения как решений в коде.
Спепление (сoupling) 
Два элемента сцеплены в отношении некоторого изменения, если изменение одного элемента требует изменения другого.
Чем слабее сцепление для одного класса изменений, тем сильнее оно мб для другого. Стараться избавиться от сцепления совсем — бессмысленно.
Проблема сцепления не в том, что сцепляются два элемента, а в том, что могут сцепляться 1-N элементов и изменения могут быть каскадными.
Сложность системы обычно состоит в том, что изменения могут приводит к неожиданным последствиям.
Как правило есть два пути реализации поведения: быстрый, но со сцеплением и медленный, но без сцепления.
Что такое опцион 
Петя хочет купить картошку за 1$. Ваня хочет продать картошку за 1$.
Если картошка нужна Пете завтра, он может дать Ване 1$ сегодня, и забрать картошку завтра. Поскольку ценность денег со временем уменьшается, имеет смысл давать не 1$, а меньше.
Если Петя не уверен, что картошка завтра понадобится, он может заплатить Ване x$ за возможность купить картошку завтра. Когда Ваня уверен, что сможет продать картошку кому-то другому, если Петя её не купит, x будет мало. Когда Ваня не уверен — x будет велико.