Совершенный код
Совершенный код [2019] Стив Макконнел
A Solid Average
Когда вместе собираются критики, они говорят о Теме, Композиции и Идее. Когда вместе собираются художники, они говорят о том, где купить дешевый скипидар
Пабло Пикассо
Первая цитата книги меня зацепила. Как человек, который посвятил 8 лет рисованию, я прекрасно понимаю аналогию. На конференциях программистов, обсуждаются тонкости и особенности языков программирования, встретить доклады об “надуровне” кодирования можно нечасто.
За примерами далеко ходить не нужно, я недавно смотрел:
Fast and Small C++ - When Efficiency Matters - Andreas Fertig - CppCon 2024
Там как раз про скипидар, а эта книга не о нём.
Общая оценка
Это средняя книга с полезными идеями. Она точно не учит плохому, а наоборот, помогает структурировать знания. Её сильная сторона — обширная библиография. Несмотря на возраст некоторых источников (80-е - 2000-е), многие из них остаются актуальными благодаря рассмотрению универсальных вопросов. На последних страницах даже представлены наборы книг для последовательного повышения своего уровня знаний.
Книга будет полезна скорее начинающим. Для меня, человека с опытом и знаниями из магистратуры по “Системной инженерии ПО”, а также читавшего трилогию Роберта Мартина (Чистая архитектура, Чистый код, Идеальный программист), Совершенный код стал повторением изученного. Книги Мартина я рекомендую к прочтению больше.
Мысли во время чтения
Блокируйте неявно сгенерированные ненужные методы и операторы
Один из принципов, упомянутых в книге: «Блокируйте неявно сгенерированные методы и операторы, которые не нужны». Этот совет сразу заставил меня задуматься о проблемах C++. Принцип выглядит, как workaround/борьба с самим языком C++. Язык создает лишнее место для выстреливания себе в ногу. Неявно создаваемые методы облегчают жизнь в одних случаях, но порождают множество ошибок в других.
При проектировании языка хорошей идей было бы сделать эти неявно сгенерированные методы через миксины. Так программисты сами выбирали бы нужное. Это соответствовало бы философии C++: «делаем только то, что нужно».
К этой же проблеме я отнес еще один принцип “по мере возможности делайте интерфейсы программными, а не семантическими”. Суть проста, компилятор/код должен не дать использовать код так, как его нельзя использовать. Например, нарушением принципа будет сделать два метода, где только семантически заложено, что метод А должен быть вызван методом Б.
Если взглянуть на C++, то семантически я должен знать, что компилятор сгенирирует конструкторы и др. Поэтому язык C++ сложен. Но можно же этого избежать, если ничего не генерировать.
В большинстве случаев используйте deep copy, а не shallow copy
Принцип использования глубокого копирования вместо поверхностного напомнил мне о Python. В Python передача объектов в аргументах может быть коварной. Один неловкий шаг — и значение аргумента по умолчанию изменяется, еще шаг в сторону и объект меняется на вызывающей стороне или не меняется.
Кажется, что где нарушены принципы, там возникают у людей проблемы. И это касается не только кода приложений, но и других систем, например, языков программирования.
Попробуй парное программирование с ИИ
В книге упоминается парное программирование как эффективный метод, повышающий качество кода и уменьшающий число ошибок. Интересно, каковы результаты могли бы быть при использовании ИИ вместо человека?
Я использую ИИ для реализации подзадач, ревью уже готового кода. разбиения задач, написания тестов, анализа кода. Возможно, можно расширить этот подход: просить разбивать на подзадачи, говорить о своих дальнейших намерениях и просить оценить их. Просить писать тесты, выявлять краевые случаи, валидировать код на соответствие требованиям. После разработки можно просить обратную связь, места, которые нужно подтянуть разработчику.
Будь пессимистом
Автор советует подходить к разработке с пессимизмом: писать “грязные” тесты, которые намеренно разрушают систему. Такой подход намного важнее “чистых” тестов, проверяющих, что код работает.
Это напоминает мне дуракоустойчивый дизайн интерфейсов: если пользователь может сделать что-то неправильно, он обязательно это сделает. Важно заранее ограничить такие возможности.
Оценивай времязатраты
У меня есть сложности с оценкой времязатрат, не хватает практики. У меня много неопределенной исследовательской работы, но я понимаю, что хотя бы начальные шаги можно и нужно оценивать.
В книге приведены полезные ссылки в разделе “28.3 Оценка графика конструирования”. Возможно, стоит глубже изучить эту тему, но источники из книги не расположили к тому, чтобы их читать.
Трудовые будни
Последние две части книги больше посвящены общим вопросам жизни программистов. Это полезно для новичков, но опытный разработчик вряд ли узнает там что-то новое. Он эти главы видит каждый день на работе.
Что почитать в дополнение
Одна из ключевых идей книги: “Код надо писать для читателя”. Если хотите углубиться в эту идею, то обратите внимание на:
- Пиши, сокращай — книга о том, как выражать мысли лаконично и понятно. Её принципы применимы не только к текстам, но и к коду: как назвать функции, переменные и сделать код удобным для чтения.
- Ум программиста. Как понять и осмыслить любой код - “сомнительно, но окей”. Для себя вынес идею, что нужно читать как можно больше кода. В книге перечислены приемы для облегчения разбора кода и уменьшения когнитивной нагрузки, как при чтении, так и написании кода для читателей. Не все приемы я стал бы применять: логическую схему работы кода готов рисовать, но распечатать код и фломастерами помечать разнородные конструкции для облегчения понимания - нет.
Совершенный код может стать хорошей отправной точкой. Она о том, что действительно важно: как писать качественный код и как организовывать процессы вокруг.