Как делают софт и карьера Проектирование: почему нельзя просто сразу начать писать код
0%

Проектирование: почему нельзя просто сразу начать писать код

Проектирование: почему нельзя просто сразу начать писать код

В предыдущей статье — Требования и аналитика — мы дошли до момента, когда в трекере лежит задача с внятными критериями приёмки. Соблазн очевиден: открыть IDE и начать. Иногда это правильный ход. Гораздо чаще между «понял задачу» и «пишу код» есть фаза, которую в учебниках называют проектированием, а в жизни — «сходил поговорил», «накидал схему», «написал RFC», «посидел полчаса с блокнотом».

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

Сразу дисклеймер про границы. Здесь мы говорим о проектировании как о фазе процесса: кто, когда, в каком виде, с кем согласовывает. Содержательная часть — как именно устроены слои, микросервисы, событийные шины и CAP-теорема — живёт в отдельном треке Архитектурные паттерны, а принципы декомпозиции — в Принципах разработки. Дублировать их не будем.

Что ломается, когда проектирования не было

Начнём не с определения, а с типичной истории. Она повторяется в разных компаниях почти дословно.

Джуну дают задачу: «сделать возможность сменить тариф в личном кабинете». Критерии приёмки написаны, макеты есть. Джун делает ровно то, что написано: форма, кнопка, запрос на бэкенд, апдейт поля plan_id в таблице accounts. Проходит ревью, проходит тестирование, уезжает в прод. Работает.

Через три недели приходит бухгалтерия: не сходится выручка. Выясняется:

  • Никто не сохранял историю смен тарифа, а она нужна для актов и для аналитики оттока. Поле перезаписывалось. История за три недели потеряна безвозвратно.
  • Смена тарифа в середине оплаченного периода не пересчитывала деньги — критерий приёмки об этом молчал, а спросить было некого, потому что аналитик считал это очевидным.
  • Если пользователь нажимал кнопку дважды подряд (а он нажимал — ответ шёл 4 секунды), создавалось два события в биллинге. Идемпотентности не было, потому что о ней не подумали.
  • Партнёрская интеграция читала accounts.plan_id напрямую из реплики базы и сломалась, когда добавили статус «смена запланирована».

Ни одна из этих проблем не является багом в коде. Код делает то, что написано. Все четыре — пропущенные решения: их никто не принял осознанно, поэтому они приняли себя сами, по умолчанию, в момент написания первой строчки.

Вот это и есть определение, которое стоит запомнить.

Проектирование — это не рисование диаграмм. Это выявление решений, которые всё равно будут приняты, и принятие их до того, как они станут дорогими.

Два разных занятия, которые называют одним словом

Слово «проектирование» покрывает как минимум два разных вида работы, и путаница между ними — источник половины конфликтов на эту тему.

Архитектурное проектирование (system design) — решения уровня системы: на что делится приложение, как компоненты общаются, где лежат данные, как система выдерживает нагрузку и отказы. Горизонт — годы. Владелец — архитектор, техлид, senior-разработчики. Это то, что спрашивают на System Design Interview, подробно разобрано в System design.

Детальное проектирование фичи (feature design, иногда «техдизайн») — решения уровня одной задачи или эпика: какие таблицы, какие эндпоинты, какие состояния, что делать при ошибке, как выкатывать. Горизонт — недели. Владелец — разработчик, который будет это делать. Именно этим вы будете заниматься каждую неделю, начиная примерно с уверенного джуна.

Джуниору говорят «проектирование — это не твоё, этим архитектор занимается», и он честно ждёт, пока ему принесут готовую схему. Не принесут. Архитектор в лучшем случае определит, что фича живёт в сервисе биллинга и ходит в существующую шину. Всё остальное — ваша работа.

Сколько проектирования нужно: дозировка

Главный вопрос не «проектировать или нет», а «сколько». Ответ зависит от одного свойства решения — обратимости.

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

Шкала обратимости технических решений

Практическое правило: объём проектирования определяется не размером задачи, а самым необратимым решением внутри неё. Задача на «добавить одно поле в API» может быть на два часа кода и на два дня обсуждений, если это публичный API, которым пользуются внешние клиенты. И наоборот: рефакторинг на три тысячи строк внутри одного модуля может не требовать вообще никакого дизайн-документа, потому что всё обратимо и покрыто тестами.

Второй фактор — цена ошибки. Сложите с обратимостью — получите матрицу, по которой удобно принимать решение «а надо ли мне тут документ».

Мартин Фаулер описал ровно эту динамику в Design Stamina Hypothesis: без дизайна вы быстрее в начале и медленнее потом, с дизайном — наоборот, и есть точка пересечения. Спор идёт только о том, где она находится для конкретного проекта. Для лендинга к рекламной кампании, который живёт три недели, она может не наступить вообще, и это нормальный инженерный выбор, а не разгильдяйство.

Из чего состоит детальное проектирование фичи

Разберём по пунктам. Это не формальный шаблон — это список вопросов, ответы на которые вы всё равно дадите, вопрос только когда.

1. Границы: где живёт изменение

Первое решение — в каком модуле/сервисе/слое появляется новый код. Обычно ответ навязан существующей архитектурой, и это хорошо. Плохо, когда ответ «а давайте новый сервис»: это самое дорогое решение из возможных, и у джуна нет данных, чтобы его принимать. Фаулер про это писал в MonolithFirst — почти все успешные микросервисные системы начинались как монолит, который научились резать по живым швам, а не по угаданным.

Полезный вопрос себе: «если бы этой фичи не было, какой модуль всё равно знал бы про эти данные?» Туда и класть.

2. Контракты: что видят снаружи

Контракт — это то, на что смогут завязаться другие. Как только кто-то завязался, менять больно. Поэтому контракты проектируются, а не «получаются».

# Фрагмент OpenAPI. Обратите внимание на три вещи, которые
# отличают продуманный контракт от случайного.
paths:
  /v1/accounts/{account_id}/plan-changes:
    post:
      summary: Запланировать или применить смену тарифа
      parameters:
        - name: Idempotency-Key
          in: header
          required: true          # 1. Идемпотентность заложена в контракт,
          schema: { type: string } #    а не «добавим потом, если задвоится»
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required: [target_plan_id]
              properties:
                target_plan_id: { type: string }
                effective_from:  # 2. Смена может быть отложенной —
                  type: string   #    это следствие бизнес-правила,
                  format: date   #    а не техническая деталь
      responses:
        "202":
          description: Смена принята; см. status для итогового состояния
          content:
            application/json:
              schema:
                type: object
                properties:
                  change_id: { type: string }
                  status:            # 3. Явная модель состояний наружу,
                    type: string     #    а не булев флаг success
                    enum: [applied, scheduled, rejected]
                  effective_from: { type: string, format: date }
        "409":
          description: Уже есть незавершённая смена тарифа

Три ошибки, которые видно на ревью чаще всего:

  • Булев флаг вместо перечисления. {"success": true} сегодня, а завтра появляется «принято, но применится первого числа», и вы либо ломаете клиентов, либо городите костыль.
  • Отсутствие идемпотентности в мутирующих операциях. Сеть не надёжна, ретраи будут, клиент нажмёт дважды. Идемпотентный ключ стоит один час на этапе дизайна и три дня расследования потом. См. паттерны устойчивости.
  • Утечка внутреннего устройства наружу. Если в ответе есть plan_id из вашей таблицы — вы только что сделали свою схему БД публичным контрактом. Про стили API и их последствия — API styles, про версионирование хорошо написано у Stripe: api-versioning.

Отдельно про контракты событий. Событие в шине — это API, у которого вы не знаете потребителей. Это самый коварный вид контракта: сломать его можно молча, а узнать об этом — через неделю от чужой команды.

3. Модель данных и путь миграции

Схема БД переживает три поколения кода. Проектируется она отдельно и заранее.

-- Плохо: тариф как одно поле. Историю не восстановить,
-- отложенную смену не выразить, «кто менял» не ответить.
ALTER TABLE accounts ADD COLUMN plan_id text NOT NULL;

-- Лучше: событие смены как отдельная сущность.
-- accounts.current_plan_id остаётся как денормализованный кэш для чтения.
CREATE TABLE plan_changes (
    id              uuid PRIMARY KEY,
    account_id      uuid NOT NULL REFERENCES accounts(id),
    from_plan_id    text NOT NULL,
    to_plan_id      text NOT NULL,
    status          text NOT NULL,      -- scheduled | applied | cancelled | failed
    effective_from  date NOT NULL,
    idempotency_key text NOT NULL,
    actor_id        uuid,               -- кто инициировал: пользователь или оператор
    created_at      timestamptz NOT NULL DEFAULT now(),
    applied_at      timestamptz
);

-- Именно этот индекс делает невозможным двойное списание при двойном клике.
CREATE UNIQUE INDEX plan_changes_idem
    ON plan_changes (account_id, idempotency_key);

-- А этот — запрещает две параллельные незавершённые смены.
CREATE UNIQUE INDEX plan_changes_one_pending
    ON plan_changes (account_id) WHERE status = 'scheduled';

Обратите внимание: два частичных уникальных индекса — это бизнес-правила, выраженные так, что их невозможно обойти из кода. Это типичное дизайн-решение, которое не видно в требованиях, но которое отличает работающую фичу от фичи, которая работает до первой гонки.

Второй обязательный вопрос — как выкатывать. Схема и код деплоятся не атомарно. Стандартный ответ — expand/contract: сначала добавили новое (совместимо со старым кодом), выкатили код, потом убрали старое отдельным релизом. Про механику — в треке DevOps и в Выбор и миграция БД. На этапе дизайна достаточно ответить: «сколько релизов нужно и что происходит, если между ними откатимся».

4. Состояния и переходы

Как только у сущности больше двух состояний, её жизненный цикл нужно нарисовать — буквально. Это занимает десять минут и вылавливает больше дыр, чем любое ревью кода.

Проверьте себя по такой диаграмме тремя вопросами: (1) есть ли состояние, из которого нет выхода; (2) что происходит, если процесс упал внутри перехода; (3) какие переходы инициирует не пользователь, а время или внешняя система. Третий вопрос почти всегда выявляет забытый крон или забытый вебхук.

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

5. Отказы и деградация

Вопрос, который джун почти никогда не задаёт сам: «что делать, если внешний вызов не ответил?» Вариантов ровно четыре, и выбрать нужно осознанно:

Стратегия Когда уместна Что нужно предусмотреть
Упасть и вернуть ошибку Операция синхронная, пользователь ждёт, повтор дешёв Внятное сообщение, код ошибки, отсутствие частичных записей
Ретрай с backoff Ошибка вероятно временная, операция идемпотентна Лимит попыток, jitter, что делать после исчерпания
Поставить в очередь и ответить «принято» Пользователю не нужен мгновенный результат Способ узнать итог, обработка «завис навсегда»
Деградировать Есть разумное поведение по умолчанию Явная пометка в UI, метрика частоты деградаций

Канон по теме — Michael Nygard, «Release It!» (Pragmatic Bookshelf); паттерны таймаута, circuit breaker и bulkhead разобраны в Resilience patterns.

6. Нефункциональные требования и наблюдаемость

Если про нагрузку, латентность и объём данных не спросили — их придумает продакшн. Полезный минимум на этапе дизайна:

  • Сколько записей в этой таблице будет через год? Через три? (Ответ «немного» не принимается — попросите порядок величины.)
  • Сколько запросов в секунду в пике? Пик — это когда?
  • Что попадает в персональные данные и где это хранится? В российском контуре это ещё и вопрос 152-ФЗ и локализации, в европейском — GDPR. Это ограничение дизайна, а не «юристы потом посмотрят».
  • Какие метрики и логи я добавлю, чтобы понять, что фича работает? Название метрики придумывается сейчас, а не во время инцидента. Про это — Наблюдаемость и дежурства и Релиз и эксплуатация.

Отдельным пунктом — безопасность. Минимальный дизайн-уровень: кто имеет право вызвать эту операцию, проверяется ли это на сервере, что будет, если подставить чужой account_id. Формальная техника — threat modelling по STRIDE, см. OWASP Threat Modeling. Даже в стартапе на десять человек 20 минут такого разговора окупаются.

Как это выглядит как процесс

Теперь соберём в поток. Вот честная картинка того, как проектирование живёт внутри спринта в команде, где процесс поставлен, но не бюрократизирован.

Три места, где эта схема ломается в реальности:

Ветка «вернуться к аналитику» не используется. Джун боится показаться глупым и додумывает требование сам. В 80% случаев угадывает, в 20% — переделка. Скажу прямо: вопрос «что должно произойти, если пользователь понижает тариф в последний день оплаченного периода» не делает вас глупым. Отсутствие этого вопроса в дизайне делает вас автором бага.

Обратная связь после столкновения с реальностью. Дизайн почти всегда оказывается частично неверным — это нормально, Парнас с Клементсом ещё в 1986 году честно написали статью «A Rational Design Process: How and Why to Fake It» о том, что идеального линейного проектирования не бывает и документ пишется задним числом как будто оно было. Проблема не в том, что дизайн изменился, а в том, что об этом никто не узнал.

«Разбить на шаги, которые можно мержить по отдельности» — самый недооценённый пункт. Хороший дизайн отвечает не только «как это устроено», но и «в каком порядке это появляется в main так, чтобы каждый шаг был безопасен». Об этом подробно в следующей статье.

Кто участвует и кто что решает

Проектирование редко бывает одиночным занятием. Вот как выглядит взаимодействие ролей на средней по размеру фиче.

Ключевое наблюдение, которое стоит вынести: QA и безопасность подключаются до кода, а не после. Вопрос тестировщика «а как я воспроизведу состояние Failed?» на этапе дизайна стоит одну строчку в схеме. Тот же вопрос через две недели стоит переделки. Это и называется shift-left, про который много говорят и мало делают. Роли и зоны ответственности подробно разобраны в Кто есть кто в команде.

Артефакты: что реально пишут

Забудьте про толстые «технические задания» из методичек. В живых командах встречаются четыре формата, и все они короткие.

Комментарий в задаче на 10 строк. Самый частый артефакт. «Делаю так-то, поля такие-то, ручка такая, при отказе биллинга кладу в очередь ретраев». Занимает пять минут, ловит половину недоразумений на ревью.

Техдизайн / RFC на 1–3 страницы. Формат, который де-факто стал стандартом в продуктовых компаниях: постановка проблемы, варианты решения, выбранный вариант, последствия, открытые вопросы. Отлично описан в разборе практики Uber и других — Scaling Engineering Teams via RFCs; открытый пример живого процесса — RFD у Oxide Computer.

ADR (Architecture Decision Record). Короткая запись именно решения и его контекста, живёт в репозитории рядом с кодом. Придумал Michael Nygard, Documenting Architecture Decisions; коллекция шаблонов — adr.github.io.

# ADR-014: Смена тарифа как отдельная сущность, а не поле в accounts

## Статус
Принято, 2026-03-04. Заменяет неявное решение из ADR-002.

## Контекст
Тариф хранится как accounts.plan_id. Требуется отложенная смена,
история для бухгалтерии и защита от двойного применения.
Партнёрская интеграция читает plan_id из реплики.

## Решение
Вводим таблицу plan_changes с явной моделью состояний.
accounts.current_plan_id сохраняем как денормализованный кэш
и обновляем в той же транзакции, что и переход в applied.

## Альтернативы
1. Поле + аудит-лог общего назначения — отклонено: лог не даёт
   гарантий уникальности и не выражает «запланировано».
2. Event sourcing для аккаунта — отклонено: непропорционально
   задаче, команда не имеет опыта эксплуатации.

## Последствия
+ История и отложенные смены доступны из коробки.
+ Двойное применение невозможно на уровне БД.
− Две точки правды; расхождение кэша нужно мониторить.
− Партнёрскую интеграцию придётся мигрировать в течение квартала.

Ценность ADR не в моменте написания, а через полтора года, когда новый человек спросит «почему тут так криво сделано». Ответ «потому что в 2026-м не было опыта эксплуатации event sourcing» — это нормальный ответ. Отсутствие ответа — это то, из чего рождаются легенды про «предыдущих идиотов».

Диаграмма. Одна, от руки или в текстовом виде рядом с кодом. Хорошая опора — C4 model Саймона Брауна: она даёт четыре уровня масштаба и снимает вечный спор «а насколько детально рисовать». Практика, которая экономит месяцы: держите диаграмму в текстовом формате (mermaid, PlantUML, Structurizr DSL) в том же репозитории, что и код. Картинка в PNG на корпоративном портале протухает за квартал и врёт.

Энтерпрайз и стартап: одна фаза, две вселенные

Это тот случай, когда разница между типами компаний максимальна. Обе крайности имеют смысл в своём контексте, и обе имеют цену. Подробно — в Энтерпрайз изнутри и Стартап изнутри.

Крупная компания / энтерпрайз Стартап /小 команда
Кто принимает решение Архитектурный комитет, TDA, владелец домена Тот, кто делает; иногда СТО
Артефакт Формальный шаблон, иногда 20+ страниц Тред в Slack, ADR на полстраницы
Срок согласования От недели до квартала От часа до дня
Что реально проверяют Соответствие стандартам, ИБ, лицензии, ПДн, влияние на смежные системы «Мы точно не закопаемся на месяц?»
Главный риск Решение устарело, пока согласовывалось Решение приняли, не зная о трёх последствиях
Что хорошего Ловятся системные и юридические косяки; есть кого спросить Обратная связь от прода за дни; дизайн проверяется реальностью
Что плохого Проектирование превращается в защиту документа Через два года половина системы — необратимые решения, принятые за пять минут

Честно про энтерпрайз: часть тяжести процесса — не глупость, а следствие цены ошибки. Когда система обслуживает миллионы людей и регулируется ЦБ, «просто попробуем и откатим» не работает: откат может быть невозможен юридически. Часть — действительно ритуал, унаследованный от времён, когда релиз был раз в полгода.

Честно про стартап: скорость реальна и это огромное преимущество для обучения. Но неоплаченный дизайн — это долг с процентами, который вы же и будете обслуживать. Разница между хорошим и плохим стартапом не в наличии документов, а в том, отличают ли там зелёную зону от красной.

Отдельная категория — аутсорс и госсектор, где формат проектной документации может быть прописан в договоре или ГОСТе (например, ГОСТ 34 и 19 серии в госзаказе). Там дизайн-документ — юридический артефакт, а не инструмент мышления, и путать эти два назначения нельзя. Подробнее — в Какие бывают проекты.

Проектирование и оценка

Просить оценку до проектирования — всё равно что просить смету до осмотра квартиры. Тем не менее просят, и с этим нужно уметь работать.

Рабочий подход, который не превращает вас в человека, который «всегда срывает сроки»:

  1. Разделяйте оценку на два акта. Первая — грубая, порядковая, до дизайна: «дни, недели или месяцы». Вторая — после дизайна, уже в терминах шагов. Явно говорите, какая из них озвучена.
  2. Называйте не число, а диапазон с причиной разброса. «3–8 дней; разброс из-за того, что не знаю, поддерживает ли биллинг отложенные операции — выясню за день». Это превращает оценку в понятный менеджеру риск, а не в обещание.
  3. Не забывайте про всё, что не код. Ревью, тесты, миграция, переключение флага, мониторинг, документация, ответы смежникам. У новичков систематическая недооценка именно здесь — кода-то на день.
  4. Проектирование — это тоже работа, у неё есть длительность. Заложите её в оценку явной строкой. «День на дизайн» — легитимная позиция.

Механика оценок, story points, покер планирования и почему всё это систематически врёт — в Оценка и планирование.

Типичные ошибки

Проектирование в вакууме. Документ написан, но не показан тем, кого он затрагивает. Дизайн, который не прошёл через чужие глаза, — это не дизайн, а ваши предположения в красивом оформлении. Минимальный ритуал: 20 минут созвона с одним человеком, который знает систему дольше вас.

Over-engineering под будущее, которого не будет. Абстрактная фабрика провайдеров платежей при одном провайдере. Плагинная архитектура для двух вариантов поведения. Kafka ради 40 событий в сутки. Проверочный вопрос: «какое конкретное известное мне требование я не смогу выполнить без этой абстракции?» Если ответа нет — это YAGNI, см. также DRY, KISS, YAGNI и Антипаттерны.

Обратная ошибка: «сделаем просто, потом отрефакторим». Работает для зелёной зоны и не работает для красной. «Потом перепишем формат события» — не бывает. Отличать эти два случая и есть профессиональный навык.

Дизайн как документ, а не как мышление. Признак: документ пишется после того, как код уже написан, ради галочки в чек-листе. Это чистые потери. Если процесс требует такого документа — пишите его честно и коротко, но не притворяйтесь, что это проектирование.

Молчаливое отклонение от дизайна. В коде оказалось иначе, ревьюер об этом не знает, документ не обновлён. Через полгода документ активно вредит, потому что ему верят.

Проектирование в одиночку в open space, где сидит человек, писавший этот модуль. Два часа чтения кода против пяти минут вопроса. Стеснительность — самая дорогая черта джуна.

Пропуск вопроса «а как мы это выключим». Любая заметная фича должна иметь способ быть отключённой без релиза: фича-флаг, конфиг, kill switch. Решается на дизайне одной строкой, спасает во время инцидента.

Что делает на этой фазе человек в зависимости от грейда

Полезно понимать, куда расти. Развёрнуто про грейды — в Грейды, здесь — только срез по проектированию.

  • Джун. Проектирует внутри одной задачи и одного модуля. Главный навык — заметить, что решение выходит за пределы задачи, и спросить. Нормально не знать ответ; ненормально не заметить вопрос.
  • Мидл. Проектирует фичу целиком, включая контракты, миграции и порядок выкатки. Умеет назвать два-три варианта и объяснить выбор. Учитывает эксплуатацию: логи, метрики, откат.
  • Сеньор. Проектирует то, что затрагивает несколько команд. Основная работа — не схема, а согласование: выяснить, кого сломает, и договориться. Умеет сознательно выбрать плохое-но-быстрое решение и явно записать долг.
  • Техлид/архитектор. Отвечает за то, чтобы решения были совместимы между собой во времени, и за то, чтобы процесс проектирования не превращался ни в анархию, ни в бюрократию.

Как этому научиться, если вы джун

Проектирование — навык, который прокачивается наблюдением и разбором, а не чтением.

  1. Читайте чужие дизайн-документы и ADR в своей компании. Это самый быстрый способ понять, как здесь принято думать. Обращайте внимание на раздел «альтернативы»: там видно ход мысли.
  2. Проводите обратное проектирование по легаси. Возьмите модуль, который вам непонятен, и восстановите: какие решения были приняты и какие ограничения их вызвали. Половина «идиотского кода» окажется разумным ответом на давно исчезнувшее ограничение.
  3. Пишите техдизайн даже там, где не просят. Десять строк в задаче. Через полгода перечитайте: увидите, чего систематически не учитываете именно вы.
  4. Ходите на дизайн-ревью чужих задач и молчите. Слушайте, какие вопросы задают опытные. Через десяток встреч вы начнёте задавать их себе сами — это и есть весь секрет.
  5. Тренируйтесь на System Design задачах, но помните: интервью — упрощённая модель. Реальное проектирование на 70% состоит из выяснения ограничений, которых на интервью просто нет. Заготовка — System design и Архитектурные решения.
  6. Освойте одну технику совместного моделирования. Например Event Storming — быстрый способ вытащить из бизнеса модель процесса: Event Storming.

Чек-лист перед первой строчкой кода

Короткий список, который реально помещается в голове. Если на все ответы есть — можно кодить.

  • Я могу назвать бизнес-правило, а не только UI-поведение.
  • Я знаю, какие данные появляются и переживают ли они три поколения кода.
  • Контракт наружу зафиксирован; в нём перечисление, а не булев флаг.
  • Мутирующая операция идемпотентна или объяснено, почему не нужно.
  • Нарисован жизненный цикл сущности; тупиковых состояний нет.
  • Известно, что делать при отказе каждой внешней зависимости.
  • Понятно, как это выкатывается и как откатывается; есть способ выключить.
  • Названы метрики/логи, по которым будет видно, что фича жива.
  • Проверено, кого это ломает: смежные команды, интеграции, отчёты.
  • Решение из красной зоны — записано и с кем-то обсуждено.
  • Работа разбита на шаги, каждый из которых можно смержить отдельно.

Мини-итог

  • Проектирование — это не диаграммы, а осознанное принятие решений, которые иначе примут себя сами и не в вашу пользу.
  • Дозировка определяется обратимостью: зелёную зону просто кодят, красную — обсуждают и записывают.
  • Минимальный набор вопросов: границы, контракты, данные и миграция, состояния, отказы, нефункциональные требования, наблюдаемость, способ выключить.
  • Артефакты короткие: комментарий в задаче, RFC на страницу, ADR, одна диаграмма в репозитории.
  • Энтерпрайз рискует утонуть в согласованиях, стартап — накопить необратимые решения; ни то ни другое не «правильно» само по себе.
  • Дизайн будет неверен частично — это норма. Ненормально не сказать об этом тем, кто на него опирался.

Источники и что почитать

  • John Ousterhout, A Philosophy of Software Design — лучшее короткое чтение про то, что такое сложность и как её уменьшать. Страница книги
  • Michael Nygard, Release It!, 2nd ed. — про отказы, таймауты и то, что система живёт в проде.
  • Mark Richards, Neal Ford, Fundamentals of Software Architecture — про архитектурные характеристики и компромиссы.
  • Michael Keeling, Design It! — практикум по дизайн-мышлению для команд.
  • David Parnas, Paul Clements, A Rational Design Process: How and Why to Fake It, 1986 — честная классика про то, почему линейного проектирования не бывает.
  • David Parnas, On the Criteria To Be Used in Decomposing Systems into Modules, 1972 — откуда вообще взялась идея скрывать решения за границами модулей.
  • Martin Fowler, Is Design Dead? и Design Stamina Hypothesis
  • C4 model — как рисовать архитектуру на четырёх уровнях детализации.
  • adr.github.io — шаблоны и инструменты для ADR.
  • Google API Design Guide — здравые правила проектирования контрактов.
  • OWASP Threat Modeling — минимальная дисциплина по безопасности на этапе дизайна.

Что дальше

Дизайн есть, чек-лист пройден — пора писать код. Следующая статья про то, как код попадает из вашей головы в main: ветки, коммиты, ревью, стандарты и главный вопрос «а когда задача считается готовой».

Разработка: ветки, код-ревью, стандарты и Definition of Done

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов