Про программирование, выпуск 6

Apr 19, 2021 00:09

Корректность

На самом деле корректный код писать довольно просто, если придерживаться нескольких правил:
  • Проверка данных на входе
  • Правильная модель данных
  • Понимание инвариантов и корретных состояний

Первый пункт вроде очевидный, но все же. Код чаще всего представляет собой слоистую структуру - роутер, код с непосредственной бизнес логикой, общие классы и модели, слой для общения с базой данных, общие утилиты. Гарантированный способ получить проблемы в коде - это мешать эти слои. Например, что-то во вводе может отсутствовать, это должно представлено ниже по стеку через сигнатуры функций или методов. Если так не делать, то в нижестоящем коде несозможно понять, какие данные придут, и приходится писать суперащищенный код без всяких на то причин. Мало того, потобный защитный код может прятать ошибки. Например, расчитывается код скидки для пользователя, вы не знаете, придет пользователь или нет, и если нет, то возвращаете ноль. Бабац, где-то ошибка и пользователь не передается, дискаунт для всех ноль. А если бы сигнатура не позволяла подобный вызов в принципе, то ошибки не было бы.

Говоря об ошибках, главная ошибки - это возвращать одну и ту же ошибку по разным поводам (в этом случае сложно сделать правильную обрбаботку в зависимости от случая), а так же просто пробрасывать ошибки вверх по стеку. Наверняка у каждого было - запускаете приложение, а оно валится с чем-то невнятным типа "file not writable". Потом окажется, что это какая-то левая подсистема в лог не могла написать.

Правильная модель данных - это то, что отличает нормальный код от лапши, в которой никто и никогда не разберется. Что значит правильная? Это значит, что в ней можно описать все состояния предметной области, и в ней не представимы состояния, которые в этой области невозможны. Это чрезвычайно помогает, т.к. часто в коде надо все возможные состояния отрабатывать (если не отрабатывать, то неуловимые баги начнутся почти сразу). Во время написания кода во время написания любого условия стоит задуматься, а что будет в противном случае? Может ничего, а может надо разбить сложное условие и отработать отдельные случаи если часть условия не выполняется. Просто сам факт рассмотрения возможных вариантов сразу повышает качество кода.

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

С корректными состояниями еще проще - система всегда должна быть в понятном состоянии. Хуже нет слуаев, когда данные есть в одном месте, но отсутствуют в другом, или статус разный, т.к. нет возможности понять, где правда. Любое место, где может произойти рассинхронизация, нужно изолировать и обложить мониторингом.

coding

Previous post Next post
Up