Исключения из YAGNI

Я всецело верю в You Aren't Gonna Need It (YAGNI) - принцип, согласно которому фичи - в том числе обобщения и абстракции - нужно добавлять в проект, только когда становится очевидно, что они необходимы, и не ранее.
Тем не менее, есть вещи, которые все-таки проще сделать раньше, и в случае которых разумными идеями или безжалостным применением YAGNI можно пренебречь. Вот мой список таких вещей:
"Ноль, один, много".
Если требования меняются от "нам нужно хранить один адрес для каждого пользователя" до "нам нужно хранить два адреса для каждого пользователя", в 9 случаях из 10 вам стоит сразу перепрыгнуть к "нам нужно хранить много адресов для каждого пользователя" с мягким ограничением в 2 адреса на стороне интерфейса, потому что существует большая вероятность, что в конце концов вам понадобится больше двух. Скорее всего, вы значительно выиграете, сделав это предположение, и даже если оно окажется неверным, ущерб будет минимальным.
Версионирование.
Это применимо к протоколам, API, форматам файлов и т.д. Хорошо, например, подумать, как клиент-серверная система будет обнаруживать и реагировать на расхождение в версиях заранее (т.е. даже когда версия только одна), тем более если вы не можете контролировать оба конца или не можете обновлять их одновременно, потому что поздно будет думать о таких вещах, когда вы обнаружите, что версия 2 все-таки нужна. На самом деле, это применение подхода "Перемены неизбежны" (Embrace Change) - принципа в сердце YAGNI.
Логирование.
Особенно для отладки после возникновения ошибки и в недетерминированных или трудно-воспроизводимых ситуациях, в которых часто добавлять логирование становится уже поздно после того, как вы узнали о проблеме.
Временные метки.
Например, время создания, как написал Саймон Уиллисон в твиттере:
Урок, который я усваиваю в каждом проекте: всегда добавляйте автозаполняемую колонку created_at
в каждую таблицу вашей БД. Каждый раз, когда вы думаете: "Здесь она не понадобится", она обязательно понадобится для отладки чего-либо через несколько недель.
Если немного обобщить, вместо булевой колонки completed
, временная nullable-колонка completed_at
, хранящая, когда это состояние было достигнуто, будет полезнее.
Сбор большего объема данных.
Обобщая "логирование" и "временные метки", собирать больше данных, чем нужно сейчас, обычно не проблема (если это не личные или какие-нибудь еще конфиденциальные данные), потому что их всегда можно выбросить. Но если вы не начнете их собирать, они пропадут навечно. Я значительно выиграл, когда сделал расчет на будущую необходимость в аудите и проверке данных, о чем требования явно не указывали. И значительно проиграл, когда выбрал минимализм, из-за чего ключевая информация была потеряна, а мои возможности позже были ограничены.
Реляционная БД.
Под этим я имею в виду, что если вам вообще нужна база данных, то вам стоит сразу начать с реляционной БД и реляционной схемы данных, даже если ваши ранние требования могут быть реализованы на "документоориентированной БД" или какой-нибудь базовой системе из файлов. Большинство данных реляционны по своей природе, и нереляционные БД - это плохой первый выбор для большинства приложений.
Если вы выберете реляционную БД типа PostgreSQL, а потом окажется, что много ваших данных больше похожи на "документы", мы можете использовать их прекрасную поддержку JSON.
Если же вы остановитесь на нереляционной БД наподобие MongoDB, то даже если сейчас ваши требования к схеме данных удовлетворены, очень вероятно, что новые "простые" требования вызовут у вас множество страданий и приведут к переписыванию на Postgres (см. разделы "How MongoDB Stores Data" и "Epilogue" в этой статье).
Этот комментарий, который я увидел на днях на Lobsters, показался мне проницательным:
Возможно, причина, по которой правило "не планируй, не абстрагируй, не проектируй на будущее" - такой хороший совет, состоит в том, что большинство людей уже пишут поверх высоко-абстрагированных и полных фич платформ, которые не нужно абстрагировать еще больше?
Мы можем позволить себе следовать YAGNI, только когда системы, с которыми мы работаем, податливы и многофункциональны. Реляционные БД - очень гибкие системы, страхующие от будущих изменений в требованиях. К примеру, мой совет в прошлой секции опирается на тот факт, что для удаления лишней колонки данных достаточно выполнить DROP COLUMN
, что практически бесплатно (ну, иногда...).
Вот мой список на данный момент, возможно я его еще дополню. Что вы думаете на этот счет? Что я пропустил?
Материал подготовлен с ❤️ редакцией Кухни IT.