<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>timcode.ru: статьи, кейсы и справочник</title>
    <link>https://timcode.ru</link>
    <atom:link href="https://timcode.ru/rss.xml" rel="self" type="application/rss+xml"/>
    <description>Backend / full-stack разработчик из Москвы, в разработке с 2014 года. Laravel, Go, Vue, PostgreSQL. Продуктовая разработка в Waviot (IoT-платформа NB-Fi), собственная платформа Mercurio для интернет-магазинов, пять open-source пакетов.</description>
    <language>ru</language>
    <item>
      <title>Чистая архитектура (Clean Architecture)</title>
      <link>https://timcode.ru/handbook/architecture/clean-architecture/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/architecture/clean-architecture/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Делает каждый сценарий приложения отдельным объектом с явным входом и выходом, а все зависимости в коде направляет внутрь, к бизнес-правилам.</description>
    </item>
    <item>
      <title>Разделение команд и запросов (CQRS)</title>
      <link>https://timcode.ru/handbook/architecture/cqrs/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/architecture/cqrs/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Команды меняют модель записи и ничего не возвращают, запросы читают отдельную модель, собранную под экран, и не трогают агрегат.</description>
    </item>
    <item>
      <title>Тактический DDD (Domain-Driven Design)</title>
      <link>https://timcode.ru/handbook/architecture/ddd/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/architecture/ddd/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Правила предметной области живут в самих объектах домена: агрегат не даёт привести себя в неверное состояние, значения проверяются при создании, а о случившемся сообщают события.</description>
    </item>
    <item>
      <title>Хранение событий (Event Sourcing)</title>
      <link>https://timcode.ru/handbook/architecture/event-sourcing/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/architecture/event-sourcing/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Вместо текущего состояния заказа хранится журнал всего, что с ним случилось, а состояние каждый раз получается проигрыванием этого журнала.</description>
    </item>
    <item>
      <title>Гексагональная архитектура (Hexagonal Architecture)</title>
      <link>https://timcode.ru/handbook/architecture/hexagonal/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/architecture/hexagonal/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Ставит предметную область в центр: ядро объявляет порты, а база, платёжная система, HTTP и почта подключаются к ним адаптерами снаружи.</description>
    </item>
    <item>
      <title>Слоистая архитектура (Layered Architecture)</title>
      <link>https://timcode.ru/handbook/architecture/layered/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/architecture/layered/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Делит приложение на слои представления, бизнес-логики и данных, где каждый слой вызывает только тот, что под ним.</description>
    </item>
    <item>
      <title>Ошибки как значения в Go (Errors and wrapping)</title>
      <link>https://timcode.ru/handbook/languages/go/01-errors-and-wrapping/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/languages/go/01-errors-and-wrapping/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Ошибка в Go - обычное значение, которое можно обернуть контекстом, проверить по смыслу и сложить с другими: так импорт прайса сообщает обо всех плохих строках сразу, а вызывающий код решает, что делать, без разбора текста.</description>
    </item>
    <item>
      <title>Readonly и перечисления в PHP (Readonly classes and enums)</title>
      <link>https://timcode.ru/handbook/languages/php/01-readonly-and-enums/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/languages/php/01-readonly-and-enums/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Статус заказа становится типом, а деньги - неизменяемым значением: опечатку в статусе и тихую правку суммы ловит язык, а не код-ревью.</description>
    </item>
    <item>
      <title>Protocol и ABC в Python (Protocols vs abstract base classes)</title>
      <link>https://timcode.ru/handbook/languages/python/01-protocols-vs-abc/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/languages/python/01-protocols-vs-abc/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Protocol описывает, что нужно вызывающему коду, и принимает любой объект подходящей формы; ABC описывает, что обязаны уметь наследники, и делится с ними общим кодом. Хранилищам файлов нужны оба, но в разных местах.</description>
    </item>
    <item>
      <title>Размеченные объединения в TypeScript (Discriminated unions)</title>
      <link>https://timcode.ru/handbook/languages/ts/01-discriminated-unions/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/languages/ts/01-discriminated-unions/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Ответ платёжного шлюза описывается объединением вариантов с общим полем kind: компилятор сам сужает тип в каждой ветке, ловит забытый вариант через never, а ошибки разбора возвращаются как значение Result, а не летят исключением.</description>
    </item>
    <item>
      <title>Шаг 1: одна функция на все способы доставки</title>
      <link>https://timcode.ru/handbook/lessons/001-refactor-to-strategy/step-1/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/001-refactor-to-strategy/step-1/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Исходный код: switch по способу доставки, внутри if по стране, цены зашиты прямо в ветках.</description>
    </item>
    <item>
      <title>Шаг 2: способы доставки за общим интерфейсом</title>
      <link>https://timcode.ru/handbook/lessons/001-refactor-to-strategy/step-2/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/001-refactor-to-strategy/step-2/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Каждая ветка switch становится своим классом с методом cost, а калькулятор только выбирает, кому отдать посылку.</description>
    </item>
    <item>
      <title>Шаг 3: реестр тарифов и правила из конфига</title>
      <link>https://timcode.ru/handbook/lessons/001-refactor-to-strategy/step-3/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/001-refactor-to-strategy/step-3/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Тарифы регистрируются по коду, а какой тариф у какого способа в какой стране - решает список правил из конфига.</description>
    </item>
    <item>
      <title>Шаг 1: SQL прямо в контроллере</title>
      <link>https://timcode.ru/handbook/lessons/002-extract-repository/step-1/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/002-extract-repository/step-1/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Исходный код: контроллер заказов сам пишет SQL, разбирает ряды и решает, можно ли отменить заказ.</description>
    </item>
    <item>
      <title>Шаг 2: шлюз таблицы</title>
      <link>https://timcode.ru/handbook/lessons/002-extract-repository/step-2/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/002-extract-repository/step-2/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Все SQL-строки для orders уезжают в класс OrdersTable, контроллер зовёт его методы, но всё ещё работает с рядами.</description>
    </item>
    <item>
      <title>Шаг 3: репозиторий в домене</title>
      <link>https://timcode.ru/handbook/lessons/002-extract-repository/step-3/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/002-extract-repository/step-3/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Заказ становится сущностью Order с правилом отмены, доступ к заказам - интерфейсом OrderRepository, а SQL уходит в одну из его реализаций.</description>
    </item>
    <item>
      <title>Шаг 1: касса зовёт всех сама</title>
      <link>https://timcode.ru/handbook/lessons/003-events-instead-of-calls/step-1/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/003-events-instead-of-calls/step-1/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Исходный код: Checkout сохраняет заказ и по очереди вызывает склад, аналитику и почту.</description>
    </item>
    <item>
      <title>Шаг 2: доменное событие и синхронный диспетчер</title>
      <link>https://timcode.ru/handbook/lessons/003-events-instead-of-calls/step-2/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/003-events-instead-of-calls/step-2/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Checkout публикует OrderPlaced, а склад, аналитика и почта подписываются на него сами.</description>
    </item>
    <item>
      <title>Шаг 3: независимые подписчики</title>
      <link>https://timcode.ru/handbook/lessons/003-events-instead-of-calls/step-3/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/lessons/003-events-instead-of-calls/step-3/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Диспетчер ловит ошибку каждого слушателя, отдаёт её в отчёт и зовёт следующих: упавшая аналитика больше не мешает письму.</description>
    </item>
    <item>
      <title>Практика: приём вебхуков АТС (PBX webhooks)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/chain-of-responsibility/practice-webhook/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/chain-of-responsibility/practice-webhook/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Облачная АТС шлёт события о звонках и повторяет их, пока не получит 2xx: подпись, дедупликация и фильтр тестовых номеров стоят звеньями цепочки, а заканчивается она маршрутизатором, который по типу события выбирает, что записать в CRM.</description>
    </item>
    <item>
      <title>Практика: команды прибору учёта по радио (Device commands)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/command/practice-device/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/command/practice-device/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Команда прибору - объект с параметрами и ожидаемым ответом: её ставят в очередь, отправляют по одной, ждут подтверждения, повторяют по таймауту и отменяют, пока она не ушла в эфир.</description>
    </item>
    <item>
      <title>Практика: поток показаний приборов учёта (Meter readings stream)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/observer/practice-meters/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/observer/practice-meters/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Счётчики воды присылают показания, а тревога, контроль связи и суточный расход подписаны на поток: подписчики хранят состояние между событиями, а пропажу связи видно только по тику часов.</description>
    </item>
    <item>
      <title>Практика: плата на производстве (Production line)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/state/practice-production/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/state/practice-production/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Печатная плата идёт по этапам монтаж -&gt; контроль -&gt; прошивка -&gt; упаковка, а сканеры на участках присылают одни и те же четыре действия: что значит &quot;передать дальше&quot; или &quot;вернуть на доработку&quot;, решает этап, на котором плата сейчас.</description>
    </item>
    <item>
      <title>Практика: цены из прайса поставщика (Supplier pricing)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/strategy/practice-pricing/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/strategy/practice-pricing/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Наценку выбирает категория товара, а описана она в конфиге: тип и параметры. Общие правила магазина применяются после любой стратегии, и стратегия не может их нарушить.</description>
    </item>
    <item>
      <title>Практика: разбор пакетов приборов учёта (Meter telemetry)</title>
      <link>https://timcode.ru/handbook/patterns/creational/factory-method/practice-telemetry/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/factory-method/practice-telemetry/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Проверка кадра одна для всех приборов, а парсер полезной нагрузки выбирает тип прибора из заголовка: это параметризованный фабричный метод, и новый тип прибора добавляется наследником, без правки конвейера.</description>
    </item>
    <item>
      <title>Практика: уведомления клиентам в Telegram (Telegram notifications)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/outbox/practice-telegram/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/outbox/practice-telegram/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Уведомление о заказе пишется в outbox одной транзакцией с заказом, а фоновый отправитель шлёт его через Bot API: пачками, с паузой на лимит, с пометкой мёртвых чатов и без дублей благодаря ключу идемпотентности.</description>
    </item>
    <item>
      <title>Практика: контрагенты из учётной системы (Repository over HTTP API)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/repository/practice-api/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/repository/practice-api/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Контрагенты живут не в нашей базе, а в учётной системе вроде 1С за HTTP API, и домен всё равно видит обычный репозиторий: страницы превращаются в обход, коды ответа в доменные ошибки, поля API в модель.</description>
    </item>
    <item>
      <title>Практика: доступ к заказу в админке (Access rules)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/specification/practice-access/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/specification/practice-access/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Правило &quot;кто может редактировать заказ&quot; собирается из маленьких спецификаций над парой пользователь и заказ, и при отказе называет условие, которое не выполнено.</description>
    </item>
    <item>
      <title>Практика: слои над медленным отчётом (Report source layers)</title>
      <link>https://timcode.ru/handbook/patterns/structural/decorator/practice-reports/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/decorator/practice-reports/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Кэш, замер времени, журнал и лимит строк над одним медленным запросом к базе: набор и порядок слоёв задаёт конфиг, и от порядка зависит, какие данные получит соседний экран.</description>
    </item>
    <item>
      <title>Композиция вместо наследования (Composition over Inheritance)</title>
      <link>https://timcode.ru/handbook/principles/composition-over-inheritance/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/composition-over-inheritance/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Поведение собирается из небольших частей, а не наследуется: новый набор каналов уведомлений - это новый список, а не новый класс.</description>
    </item>
    <item>
      <title>Не повторяйся, не усложняй, не делай впрок (DRY, KISS, YAGNI)</title>
      <link>https://timcode.ru/handbook/principles/dry-kiss-yagni/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/dry-kiss-yagni/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Три коротких правила против лишнего кода: одно знание - в одном месте, простое решение вместо хитрого, и ничего &quot;на будущее&quot;.</description>
    </item>
    <item>
      <title>Закон Деметры (Law of Demeter)</title>
      <link>https://timcode.ru/handbook/principles/law-of-demeter/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/law-of-demeter/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Объект общается только с ближайшими соседями: спрашивает заказ, куда его везти, а не лезет через заказ в покупателя и его адрес.</description>
    </item>
    <item>
      <title>Принцип инверсии зависимостей (Dependency Inversion Principle)</title>
      <link>https://timcode.ru/handbook/principles/solid/dependency-inversion/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/solid/dependency-inversion/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Модули верхнего уровня зависят от абстракций, а не от деталей: сервис уведомлений знает порт Mailer, а SMTP - деталь, которая подключается снаружи.</description>
    </item>
    <item>
      <title>Принцип разделения интерфейсов (Interface Segregation Principle)</title>
      <link>https://timcode.ru/handbook/principles/solid/interface-segregation/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/solid/interface-segregation/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Клиент не должен зависеть от методов, которыми не пользуется: печать и сканирование - отдельные узкие интерфейсы, а не одно &quot;устройство&quot;.</description>
    </item>
    <item>
      <title>Принцип подстановки Лисков (Liskov Substitution Principle)</title>
      <link>https://timcode.ru/handbook/principles/solid/liskov-substitution/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/solid/liskov-substitution/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Подтип должен работать везде, где ждут базовый тип: хранилище только для чтения не наследует запись, которую не умеет выполнять.</description>
    </item>
    <item>
      <title>Принцип открытости/закрытости (Open/Closed Principle)</title>
      <link>https://timcode.ru/handbook/principles/solid/open-closed/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/solid/open-closed/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Модуль открыт для расширения и закрыт для изменения: новый способ оплаты подключается к кассе без правки её кода.</description>
    </item>
    <item>
      <title>Принцип единственной ответственности (Single Responsibility Principle)</title>
      <link>https://timcode.ru/handbook/principles/solid/single-responsibility/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/principles/solid/single-responsibility/</guid>
      <pubDate>Fri, 16 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>У модуля одна причина для изменения: подсчёт продаж и форматирование отчёта меняются по разным причинам, поэтому живут порознь.</description>
    </item>
    <item>
      <title>Очередь перед чужим API</title>
      <link>https://timcode.ru/articles/queue-before-foreign-api</link>
      <guid isPermaLink="true">https://timcode.ru/articles/queue-before-foreign-api</guid>
      <pubDate>Sun, 11 Oct 2026 00:00:00 GMT</pubDate>
      <category>статья</category>
      <description>Почему между вебхуком и внешней CRM всегда стоит очередь, и какие три вещи делают её надёжной.</description>
    </item>
    <item>
      <title>Цепочка обязанностей (Chain of Responsibility)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/chain-of-responsibility/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/chain-of-responsibility/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Передаёт запрос по цепочке обработчиков: каждый либо обрабатывает его сам, либо отдаёт следующему, и отправитель не знает, кто в итоге ответит.</description>
    </item>
    <item>
      <title>Практика: middleware входящего запроса (Request middleware)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/chain-of-responsibility/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/chain-of-responsibility/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Лимит запросов, аутентификация и валидация как звенья перед обработчиком: каждое может ответить само и остановить цепочку, а от порядка звеньев зависит, кого и от чего они защищают.</description>
    </item>
    <item>
      <title>Команда (Command)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/command/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/command/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Превращает запрос в объект: его можно сохранить, передать, выполнить позже и отменить, а тот, кто его запускает, не знает, что именно он делает.</description>
    </item>
    <item>
      <title>Практика: редактор с undo/redo (Undo history)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/command/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/command/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>История правок документа из команд: отмена и повтор с курсором, обрезка ветки повтора, склейка набранных подряд символов и правило, что неудачная правка в историю не попадает.</description>
    </item>
    <item>
      <title>Интерпретатор (Interpreter)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/interpreter/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/interpreter/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Правила маленького языка становятся деревом объектов, и каждый узел сам вычисляет свою часть выражения.</description>
    </item>
    <item>
      <title>Практика: фильтры товаров (Product filter language)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/interpreter/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/interpreter/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Маркетолог пишет условие подборки строкой, а код превращает её в дерево выражений и проверяет на каждом товаре; опечатка ловится при разборе, с позицией в строке.</description>
    </item>
    <item>
      <title>Итератор (Iterator)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/iterator/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/iterator/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Даёт обойти коллекцию по одному элементу, не раскрывая, как она устроена внутри.</description>
    </item>
    <item>
      <title>Практика: постраничный обход API заказов (Paginated iterator)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/iterator/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/iterator/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Итератор прячет пагинацию внешнего API: клиент видит один длинный поток заказов, а следующая страница запрашивается, только когда до неё дошли.</description>
    </item>
    <item>
      <title>Посредник (Mediator)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/mediator/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/mediator/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Убирает прямые связи между объектами: каждый говорит только с посредником, а правила их взаимодействия собраны в одном месте.</description>
    </item>
    <item>
      <title>Практика: форма оформления заказа (Checkout form)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/mediator/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/mediator/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Поля формы зависят друг от друга: доставка прячет и показывает адрес, страна меняет список способов, промокод пересчитывает итог. Посредник CheckoutForm собирает эти правила в одном месте и не даёт уведомлениям ходить по кругу.</description>
    </item>
    <item>
      <title>Снимок (Memento)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/memento/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/memento/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Объект сохраняет своё состояние в непрозрачный снимок и потом восстанавливается из него, не раскрывая внутренностей тому, кто снимки хранит.</description>
    </item>
    <item>
      <title>Практика: черновики анкеты (Form drafts)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/memento/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/memento/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Длинная заявка сохраняется сама: снимки по таймеру с лимитом, именованные точки для отката и черновик, который переживает перезагрузку страницы и узнаёт чужой формат.</description>
    </item>
    <item>
      <title>Наблюдатель (Observer)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/observer/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/observer/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Объект сообщает об изменениях всем, кто подписался, и не знает, кто они: подписчиков можно добавлять и убирать, не трогая источник.</description>
    </item>
    <item>
      <title>Практика: доменные события заказа (Domain event dispatcher)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/observer/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/observer/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Заказ создан или отменён, а почта, склад и аналитика узнают об этом через диспетчер событий: подписчики падают, отписываются на ходу и публикуют новые события, и рассылка должна это пережить.</description>
    </item>
    <item>
      <title>Состояние (State)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/state/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/state/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Объект меняет поведение вместе со своим состоянием: каждое состояние — отдельный объект, и вместо if (state === ...) в каждом методе контекст просто передаёт вызов текущему состоянию.</description>
    </item>
    <item>
      <title>Практика: жизненный цикл заказа (Order lifecycle)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/state/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/state/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Заказ проходит путь от «новый» до «доставлен», «отменён» или «возврат»: каждый статус решает, какие события допустимы, что сделать с деньгами на переходе и как объяснить отказ.</description>
    </item>
    <item>
      <title>Практика: расчёт доставки (Shipping rates)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/strategy/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/strategy/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Способ доставки выбирается правилами из конфига, а не if в коде: страна, вес и сумма заказа решают, какая стратегия посчитает цену.</description>
    </item>
    <item>
      <title>Шаблонный метод (Template Method)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/template-method/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/template-method/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Порядок шагов алгоритма фиксирует базовый класс, а наследники подставляют только сами шаги и, если нужно, меняют поведение крючков.</description>
    </item>
    <item>
      <title>Практика: экспорт платёжного реестра (Payment registry export)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/template-method/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/template-method/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Реестр платежей уходит в разные банки в разных форматах, но проверка платежей, итоговая строка и контрольная сумма одни на всех, и ни один банк не может их обойти.</description>
    </item>
    <item>
      <title>Посетитель (Visitor)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/visitor/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/visitor/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Новые операции над набором классов без правки самих классов: каждая операция живёт в своём объекте, а узел только говорит, какой он.</description>
    </item>
    <item>
      <title>Практика: НДС и чек по заказу (Order visitors)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/visitor/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/visitor/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Заказ из товаров, скидок, доставки и упаковки, а над ним растёт список операций: НДС, фискальный чек, проверка. Операции живут в посетителях с состоянием, узлы заказа остаются данными.</description>
    </item>
    <item>
      <title>Абстрактная фабрика (Abstract Factory)</title>
      <link>https://timcode.ru/handbook/patterns/creational/abstract-factory/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/abstract-factory/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Создаёт семейство связанных объектов целиком, чтобы клиент не мог смешать продукты разных семейств.</description>
    </item>
    <item>
      <title>Практика: платёжные провайдеры (Payment providers)</title>
      <link>https://timcode.ru/handbook/patterns/creational/abstract-factory/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/abstract-factory/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Платёжный провайдер — это семейство: приём платежа, возвраты и разбор вебхуков. Возврат, ушедший не тому провайдеру, который принял платёж, — реальный инцидент, и абстрактная фабрика делает его невозможным по построению.</description>
    </item>
    <item>
      <title>Строитель (Builder)</title>
      <link>https://timcode.ru/handbook/patterns/creational/builder/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/builder/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Собирает сложный объект по шагам: обязательные части, необязательные в любом порядке, одна проверка в конце.</description>
    </item>
    <item>
      <title>Практика: запрос отчёта (Report query)</title>
      <link>https://timcode.ru/handbook/patterns/creational/builder/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/builder/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Строитель SQL-запроса для отчётов: значения только в параметрах, пагинация с границами, и неизменяемость, из-за которой базовый запрос можно делить между отчётами без сюрпризов.</description>
    </item>
    <item>
      <title>Практика: импорт прайс-листов (Price list import)</title>
      <link>https://timcode.ru/handbook/patterns/creational/factory-method/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/factory-method/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Конвейер импорта один для всех поставщиков, а парсер зависит от формата файла: его создаёт наследник, и ровно это делает конвейер проверяемым без файлов.</description>
    </item>
    <item>
      <title>Прототип (Prototype)</title>
      <link>https://timcode.ru/handbook/patterns/creational/prototype/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/prototype/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Новый объект создаётся копией уже настроенного, а глубину копии решает сам объект.</description>
    </item>
    <item>
      <title>Практика: КП из шаблона (Quote from template)</title>
      <link>https://timcode.ru/handbook/patterns/creational/prototype/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/prototype/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Копия коммерческого предложения для нового клиента: сбросить идентичность, продублировать строки, оставить общими товары каталога. Глубина копии — бизнес-решение, а не техническая деталь.</description>
    </item>
    <item>
      <title>Одиночка (Singleton)</title>
      <link>https://timcode.ru/handbook/patterns/creational/singleton/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/singleton/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Гарантирует один экземпляр на процесс и даёт к нему глобальную точку доступа. Первое полезно, второе почти всегда вредно.</description>
    </item>
    <item>
      <title>Практика: тарифы, загруженные один раз (Loaded once)</title>
      <link>https://timcode.ru/handbook/patterns/creational/singleton/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/singleton/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Единственность без глобальной точки доступа: справочник тарифов загружается один раз на процесс, потокобезопасно, а клиенты получают его через конструктор и подменяют в тестах.</description>
    </item>
    <item>
      <title>Преобразователь данных (Data Mapper)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/data-mapper/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/data-mapper/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Отдельный объект переносит данные между доменной моделью и хранилищем, так что модель не знает ни таблиц, ни колонок, ни того, что её вообще сохраняют.</description>
    </item>
    <item>
      <title>Практика: заказ в двух таблицах (Order mapper)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/data-mapper/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/data-mapper/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Маппер собирает заказ с деньгами, почтой и статусом из двух таблиц, раскладывает его обратно, удаляет снятые строки заказа и не пускает в модель битые данные из базы.</description>
    </item>
    <item>
      <title>Доменное событие (Domain Event)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/domain-event/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/domain-event/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Агрегат записывает, что с ним случилось, в виде неизменяемых фактов в прошедшем времени, а реагируют на эти факты другие части системы: агрегат не знает ни о почте, ни о биллинге.</description>
    </item>
    <item>
      <title>Практика: публикация событий после сохранения (Publishing domain events)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/domain-event/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/domain-event/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Подписка меняет тариф, биллинг и почта узнают об этом из событий, но только если изменение действительно записано в базу: событие о том, чего нет в базе, хуже, чем никакого.</description>
    </item>
    <item>
      <title>Нулевой объект (Null Object)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/null-object/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/null-object/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Вместо null подставляет объект с тем же интерфейсом и нейтральным поведением, чтобы код не проверял на null перед каждым вызовом.</description>
    </item>
    <item>
      <title>Практика: гость, лояльность и аналитика (Shop profile)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/null-object/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/null-object/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Гость вместо null-пользователя, отсутствующая программа лояльности и выключенная аналитика как нулевые объекты, которые выбираются в одном месте, и ненайденный заказ, который нулевым объектом быть не должен.</description>
    </item>
    <item>
      <title>Outbox (Transactional Outbox)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/outbox/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/outbox/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Событие о бизнес-изменении записывается в ту же базу и в той же транзакции, что и само изменение, а в брокер его отправляет отдельный процесс: данные и событие не расходятся, даже если брокер лежит.</description>
    </item>
    <item>
      <title>Практика: надёжный отправитель outbox (Outbox relay)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/outbox/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/outbox/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Брокер то отказывает, то теряет подтверждения, а события одного заказа должны прийти по порядку и ровно один раз в смысле результата: отправитель повторяет, получатель отбрасывает дубли.</description>
    </item>
    <item>
      <title>Репозиторий (Repository)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/repository/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/repository/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Даёт предметной области коллекцию сущностей с методами на её языке и прячет за ней, где и как они хранятся.</description>
    </item>
    <item>
      <title>Практика: один контракт на два хранилища (Repository contract tests)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/repository/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/repository/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Репозиторий в памяти и репозиторий в JSON-файле проходят один и тот же набор тестов: копии вместо общих объектов, поиск по критерию и конфликт версий.</description>
    </item>
    <item>
      <title>Сервисный слой (Service Layer)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/service-layer/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/service-layer/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Собирает сценарии приложения в один слой: контроллер, консольная команда и очередь вызывают один метод сервиса, а не повторяют шаги каждый у себя.</description>
    </item>
    <item>
      <title>Практика: регистрация на мероприятие (Event registration)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/service-layer/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/service-layer/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Регистрация на лекцию с ограниченным числом мест: сервис принимает проверенную команду, держит транзакцию вокруг сценария, отдаёт DTO вместо сущности и шлёт письмо только после записи.</description>
    </item>
    <item>
      <title>Спецификация (Specification)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/specification/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/specification/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Бизнес-правило становится отдельным объектом с одним вопросом «подходит ли кандидат», и одно и то же правило проверяет объект, отбирает список и собирается с другими через «и», «или», «не».</description>
    </item>
    <item>
      <title>Практика: аудитория рассылки (Mailing audience)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/specification/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/specification/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Одно правило отбора клиентов проверяет клиента в памяти и переводится в SQL WHERE с параметрами, так что приложение и база отбирают одних и тех же людей.</description>
    </item>
    <item>
      <title>Единица работы (Unit of Work)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/unit-of-work/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/unit-of-work/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Собирает все изменения бизнес-операции (новые, изменённые и удалённые объекты) и записывает их в хранилище одним проходом в конце, а не по одному в момент каждой правки.</description>
    </item>
    <item>
      <title>Практика: перевод и заказ в одной транзакции (Unit of Work)</title>
      <link>https://timcode.ru/handbook/patterns/enterprise/unit-of-work/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/enterprise/unit-of-work/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Оформление заказа списывает деньги клиента, зачисляет их магазину и уменьшает остатки склада. Единица работы держит все эти объекты, сама находит изменённые и записывает их в одной транзакции: всё или ничего.</description>
    </item>
    <item>
      <title>Адаптер (Adapter)</title>
      <link>https://timcode.ru/handbook/patterns/structural/adapter/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/adapter/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Даёт старому или чужому классу тот интерфейс, которого ждёт клиент, не меняя ни класс, ни клиента.</description>
    </item>
    <item>
      <title>Практика: SMS через старый шлюз (SMS gateway adapter)</title>
      <link>https://timcode.ru/handbook/patterns/structural/adapter/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/adapter/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Старый SMS-шлюз подключается к интерфейсу уведомлений: адаптер переводит номера телефонов в формат шлюза, а числовые коды ответа в причины, по которым приложение решает, что делать дальше.</description>
    </item>
    <item>
      <title>Мост (Bridge)</title>
      <link>https://timcode.ru/handbook/patterns/structural/bridge/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/bridge/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Разделяет иерархию на две — абстракцию и реализацию, — чтобы каждая росла сама по себе, а не перемножалась с другой.</description>
    </item>
    <item>
      <title>Практика: отчёты в разных форматах (Report renderers)</title>
      <link>https://timcode.ru/handbook/patterns/structural/bridge/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/bridge/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Два отчёта и три формата вывода без шести классов: отчёт решает, что показать, рендерер — как это записать, и новый формат не трогает отчёты.</description>
    </item>
    <item>
      <title>Компоновщик (Composite)</title>
      <link>https://timcode.ru/handbook/patterns/structural/composite/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/composite/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Дерево из простых и составных объектов с одним интерфейсом: клиент спрашивает узел, не выясняя, лист это или контейнер.</description>
    </item>
    <item>
      <title>Практика: цена корзины с наборами (Bundle pricing)</title>
      <link>https://timcode.ru/handbook/patterns/structural/composite/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/composite/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Наборы товаров со своей скидкой, вложенные друг в друга: цена считается по дереву, а дерево приходит из каталога, где редактор может ошибиться.</description>
    </item>
    <item>
      <title>Декоратор (Decorator)</title>
      <link>https://timcode.ru/handbook/patterns/structural/decorator/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/decorator/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Добавляет объекту поведение обёрткой с тем же интерфейсом: обёртки складываются в любом количестве и порядке, а исходный класс не меняется.</description>
    </item>
    <item>
      <title>Практика: клиент курсов валют (API client layers)</title>
      <link>https://timcode.ru/handbook/patterns/structural/decorator/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/decorator/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Ретраи, кэш и журнал как слои поверх одного клиента внешнего API: каждый слой простой, а поведение целого определяет порядок, в котором их сложили.</description>
    </item>
    <item>
      <title>Фасад (Facade)</title>
      <link>https://timcode.ru/handbook/patterns/structural/facade/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/facade/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Даёт один простой вход в набор подсистем: клиент вызывает одну операцию, а порядок шагов и связи между частями знает фасад.</description>
    </item>
    <item>
      <title>Практика: оформление заказа (Place order)</title>
      <link>https://timcode.ru/handbook/patterns/structural/facade/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/facade/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Оформление заказа — это резерв на складе, списание оплаты и уведомление. Фасад PlaceOrder прячет не только порядок шагов, но и то, что делать, когда шаг не удался.</description>
    </item>
    <item>
      <title>Приспособленец (Flyweight)</title>
      <link>https://timcode.ru/handbook/patterns/structural/flyweight/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/flyweight/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Много мелких объектов делят одно неизменяемое общее состояние, а уникальное хранят у себя или получают параметрами.</description>
    </item>
    <item>
      <title>Практика: стили ячеек таблицы (Cell styles)</title>
      <link>https://timcode.ru/handbook/patterns/structural/flyweight/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/flyweight/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Десять тысяч ячеек выгрузки делят три стиля: стиль неизменяемый и приходит из пула по ключу, а правка стиля одной ячейки не задевает соседей, потому что создаёт новый стиль, а не меняет общий.</description>
    </item>
    <item>
      <title>Заместитель (Proxy)</title>
      <link>https://timcode.ru/handbook/patterns/structural/proxy/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/proxy/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Подставляет вместо объекта другой с тем же интерфейсом, который решает, когда и пускать ли вызов дальше.</description>
    </item>
    <item>
      <title>Практика: кэш репозитория товаров (Caching proxy)</title>
      <link>https://timcode.ru/handbook/patterns/structural/proxy/practice/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/structural/proxy/practice/</guid>
      <pubDate>Fri, 09 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Кэширующий заместитель перед медленным репозиторием: ответы из памяти с TTL, сброс при записи и честная граница — запись мимо заместителя кэш не видит.</description>
    </item>
    <item>
      <title>Стратегия (Strategy)</title>
      <link>https://timcode.ru/handbook/patterns/behavioral/strategy/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/behavioral/strategy/</guid>
      <pubDate>Thu, 08 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Выносит семейство взаимозаменяемых алгоритмов в отдельные объекты, чтобы менять их без правки кода, который их использует.</description>
    </item>
    <item>
      <title>Фабричный метод (Factory Method)</title>
      <link>https://timcode.ru/handbook/patterns/creational/factory-method/</link>
      <guid isPermaLink="true">https://timcode.ru/handbook/patterns/creational/factory-method/</guid>
      <pubDate>Thu, 08 Oct 2026 00:00:00 GMT</pubDate>
      <category>справочник</category>
      <description>Общий алгоритм живёт в базовом классе, а решение «какой именно объект создать» отдаётся наследникам.</description>
    </item>
    <item>
      <title>Майятрица: калькулятор, админка и сайт, три кодовые базы за два года</title>
      <link>https://timcode.ru/cases/mayatriza</link>
      <guid isPermaLink="true">https://timcode.ru/cases/mayatriza</guid>
      <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>Долгий клиент: эзотерический сайт с расчётом «майянской матрицы» по дате рождения. С 2024 года написал с нуля три кодовые базы: сайт на Laravel 11, отдельную админку на MoonShine и нынешний сайт на Laravel 13 с новым дизайном, который прорабатывал вместе с заказчицей, и своей админкой на Inertia, React и shadcn. Расчёты сверены с документами заказчицы, клипы перекодирует ffmpeg.</description>
    </item>
    <item>
      <title>Магазин упаковки: задачи вокруг старого OpenCart, не ломая его</title>
      <link>https://timcode.ru/cases/lpack</link>
      <guid isPermaLink="true">https://timcode.ru/cases/lpack</guid>
      <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>Оптово-розничный магазин упаковки в Петербурге с учётом в 1С. За год вокруг боевого OpenCart 2.3 появились экран показателей отдела продаж, видеораздел с фоновой конвертацией, портал аттестации сотрудников, отчёт по трафику и демо новой витрины на Mercurio. Магазин при этом не останавливался.</description>
    </item>
    <item>
      <title>Магазин офисной мебели, 2022-2026</title>
      <link>https://timcode.ru/cases/office-furniture-shop</link>
      <guid isPermaLink="true">https://timcode.ru/cases/office-furniture-shop</guid>
      <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>Веду prvoffice.ru с нуля четвёртый год: своя админка, своя витрина, три редизайна, три этапа поиска и массовое редактирование каталога.</description>
    </item>
    <item>
      <title>Учёт производства с нуля: платы, сканер и один маршрут в коде</title>
      <link>https://timcode.ru/cases/factory</link>
      <guid isPermaLink="true">https://timcode.ru/cases/factory</guid>
      <pubDate>Thu, 01 Jan 2026 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>Написал систему учёта плат для производства Waviot: сначала прототип на готовой админке, потом своя платформа. С июня 2026 года цех ведёт в ней каждую плату, и теперь в неё переезжает всё производство с легаси 2016 года.</description>
    </item>
    <item>
      <title>Mercurio: своя платформа для интернет-магазинов</title>
      <link>https://timcode.ru/cases/mercurio</link>
      <guid isPermaLink="true">https://timcode.ru/cases/mercurio</guid>
      <pubDate>Wed, 01 Jan 2025 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>С 2025 года строю Mercurio: платформу, где сырьё поставщиков неизменяемо, человек правит только решения, а каталог собирается детерминированно. Два клиента, обе витрины пока на демо-стендах.</description>
    </item>
    <item>
      <title>На один сервис меньше: перенос HES в сервер авторизации</title>
      <link>https://timcode.ru/cases/hes-to-auth</link>
      <guid isPermaLink="true">https://timcode.ru/cases/hes-to-auth</guid>
      <pubDate>Mon, 01 Jan 2024 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>Два самописных PHP-сервиса Waviot делили один интерфейс: экраны жили в auth, их бэкенд в HES. Перенёс HES внутрь auth так, что фронт не заметил, и закрыл один сервис с отдельным деплоем.</description>
    </item>
    <item>
      <title>Кабинет и телеметрия IoT-платформы: с Zend Framework 2 на Laminas и PHP 8</title>
      <link>https://timcode.ru/cases/zend-to-laminas</link>
      <guid isPermaLink="true">https://timcode.ru/cases/zend-to-laminas</guid>
      <pubDate>Sat, 01 Jan 2022 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>Перевёл кабинет клиентов и бэкенд телеметрии Waviot с Zend Framework 2.3 и PHP 5.6 на Laminas и PHP 8 без остановки платформы, а потом закрепил результат: PSR-12, миграции БД, Sentry.</description>
    </item>
    <item>
      <title>Экран отдела продаж: сделки из Мегаплана, звонки из Mango Office</title>
      <link>https://timcode.ru/cases/prime-wood-sales-screen</link>
      <guid isPermaLink="true">https://timcode.ru/cases/prime-wood-sales-screen</guid>
      <pubDate>Wed, 01 Jan 2020 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>Для отдела продаж Prime Wood сделал экран на офисный монитор: план месяца, оплаты за день, необработанные заявки и звонки по менеджерам. PHP без фреймворка и крон, потому что этого хватало. Работу с API Mango Office потом вынес в Laravel-пакет.</description>
    </item>
    <item>
      <title>Магазин мебели: с самописной CMS на OpenCart за два месяца</title>
      <link>https://timcode.ru/cases/prime-wood-opencart</link>
      <guid isPermaLink="true">https://timcode.ru/cases/prime-wood-opencart</guid>
      <pubDate>Tue, 01 Jan 2019 00:00:00 GMT</pubDate>
      <category>кейс</category>
      <description>В одиночку перенёс prime-wood.ru с самописной MyCMS 2013 года на OpenCart, релиз перед Новым годом. Покупатели смены движка не заметили, магазин работает на этой платформе седьмой год.</description>
    </item>
  </channel>
</rss>
