Кто-то порекомендовал книгу Стива Магуайра Writing Solid Code, сказав, что она изменила их взгляды на программирование. Я прочитал второе издание (которое трудно найти) и отметил рекомендации, которые мне понравились. Эта статья в основном представляет собой их список, но в конце у меня есть несколько общих комментариев. (Обратите внимание, что некоторые рекомендации я экстраполировал, а другие применил по-своему.)

Рекомендации / советы

Можно писать программы без ошибок.

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

Используйте типизированный язык.

Запустите модульные тесты.

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

Пишите защитный код, но регистрируйте/подтверждайте/предупреждайте, если возникают непредвиденные условия.

При оптимизации или переписывании рассмотрите что-то вроде Ученый — возьмите еще одну простую, медленную версию алгоритма и сравните результаты.

Яма успеха — проектирование подсистем, которые сложно использовать неправильно.

Подумайте о своих интерфейсах с точки зрения вызывающего абонента. Насколько удобочитаемым будет сайт вызова? (В этом помогает написание модульных тестов или выполнение TDD.)

Также подумайте о UX.

Запустите покрытие кода, чтобы обнаружить логику, которая не покрыта.

Протестируйте код обработки ошибок.

Просьба разработчиков проверять коды возврата ошибок приводит к ошибкам, когда они забывают об этом. Рассмотрите исключения или другие методы, которые трудно игнорировать. Избегайте смешивания значений ошибок (таких как null или -1) с реальными данными.

Функции должны иметь ровно одну четко определенную цель.

Проверяйте аргументы и не допускайте недопустимых. Не допускайте ввода «магических чисел», которые делают что-то особенное (например, 0 заставляет функцию делать что-то совершенно другое).

Избегайте магических чисел и жестко закодированных значений в целом.

Также избегайте логических аргументов; это затрудняет чтение сайтов звонков. Функция также может выполнять несколько действий.

Тестовые граничные условия.

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

Сделайте все максимально ясным и очевидным.

Лучшие функции всегда успешны; обработка ошибок не требуется.

Учитывайте риски при оценке проекта.

Старайтесь избегать специального кода. (Один из моих коллег недавно напомнил мне о паттерне Null Object, и мы упростили код, упростив его.)

Избавьтесь от лишних условных выражений.

Избегайте вложенных тернарных (условных) операторов.

Множественные точки возврата функции не обязательно плохи.

Предпочитайте реализации, которые легко понять (и отладить).

Избегайте избыточности. (Аналогично СУХОЙ.)

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

Избегайте рискованных языковых идиом. (Это напомнило мне книгу Крокфорда JavaScript: The Good Parts.)

Остерегайтесь ошибок приоритета оператора. К этому может привести смешивание типов операторов.

Изолируйте обработку ошибок.

Предпочитайте очевидный и скучный код умным трюкам. Пишите простой код, который будет легко понять начинающим программистам. (Согласен на 100%.)

Избегайте неясной терминологии. Будь понятен.

Не полагайтесь на внутреннее устройство или другие детали реализации.

Избегайте глобальных переменных.

Избегайте «однострочного подхода». (Я видел однострочное выражение LINQ, которое выходило за пределы экрана...)

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

Устраняйте причину, а не симптом. Отслеживайте ошибки до их источника.

Не проводите рефакторинг без тестов.

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

Избегайте гибких конструкций и функций. Держите вещи простыми и легко тестируемыми.

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

Тестируйте свой код/функции на ходу. В противном случае слишком легко пропустить тестирование, особенно при плотном графике. И всегда тестируйте, независимо от расписания.

Не полагайтесь на QA, чтобы найти ошибки в вашем коде; это твоя работа. И не обвиняйте QA в обнаружении ваших ошибок.

Сосредоточьтесь на написании простого кода, который легко поддерживать и тестировать.

Примите философию «ноль ошибок».

Обзор

Для меня это было похоже на возвращение в прошлое на 20 лет. (Это неудивительно, поскольку первое издание было опубликовано в 1993 году.) Я помню, как писал код и просматривал пути в отладчике примерно в 2000 году, и это один из основных методов, рекомендованных автором. Это сработало; В компании у меня была репутация человека с очень небольшим количеством дефектов. Проблема заключалась в том, что если я менял код, мне приходилось утомительно перебирать ветки снова. Это заставило меня сопротивляться запросам на изменение.

В конце концов ведущий конференции познакомил меня с модульным тестированием, и я обнаружил, что этот метод дает мне те же преимущества, что и пошаговое выполнение кода. Я также мог бы изменить код и быстро запустить тесты для проверки регрессии. Я узнал об Экстремальном программировании (XP) и Разработке через тестирование (TDD); теперь я пишу тесты как само собой разумеющееся. Автор книги Writing Solid Code мимоходом упоминает модульное тестирование, но в книге это не рассматривается.

Тем не менее, многие советы автора вполне верны. Это напоминает мне превосходные Руководство по проектированию фреймворка; поскольку идеи из обеих книг возникли в Microsoft, это неудивительно.

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

В предыдущем разделе я не перечислил рекомендации, относящиеся к языку C, а также пропустил те, с которыми я не согласен (например, пошаговое выполнение кода в отладчике). Если вас это интересует, то рекомендую прочитать книгу.

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