# Swift Implementation Patterns Mastermind Этот документ описывает нормативные паттерны реализации кода на Swift. ## 1. Concurrency & State Ownership **Problem**: Состояние гонки (race conditions) и неопределённое поведение при многопоточности. **Rule**: Каждая stateful-возможность (Capability) или сервис принадлежат конкретному `actor`. Межмодульный обмен — только через `Sendable` неизменяемые типы (value types). `MainActor` используется исключительно для UI-проекций. **Apply when**: При проектировании хранилищ, сервисов и вью-моделей. **Avoid**: Использование `lock`, `DispatchQueue` для синхронизации состояния вручную; захват мутабельного состояния в замыканиях. **Trade-offs**: Требует понимания Swift Concurrency и использования `await`. **Verification**: Swift 6 Strict Concurrency не должен выдавать предупреждений и ошибок. ## 2. Bounded Async Streams **Problem**: Неконтролируемое накопление событий в очередях (backpressure) приводит к утечкам памяти и задержкам. **Rule**: Все `AsyncStream` должны иметь ограниченный буфер (bounded) и явную политику обработки переполнения (`dropOldest`, `dropNewest` или `coalesce`). **Apply when**: Для потоков аудио-фреймов, скриншотов и событий UI. **Avoid**: Создание неограниченных потоков событий. **Verification**: Каждый стрим должен иметь тесты на поведение при переполнении. ## 3. Lightweight UDF (Unidirectional Data Flow) **Problem**: Сложная двусторонняя синхронизация UI и бизнес-логики. **Rule**: Использование однонаправленного потока данных: Immutable State → View → Intent (Action) → Service/Reducer → New State. Без обязательной зависимости от тяжелых фреймворков (TCA). **Apply when**: В реализации Companion Island и экранов управления. **Avoid**: Прямая мутация состояния из View; использование `Binding` для бизнес-логики. **Verification**: View зависит только от `State` и отправляет `Intents`. ## 4. Boundary State Machines **Problem**: Неявные переходы между состояниями (например, Collectors) приводят к трудновоспроизводимым багам. **Rule**: Использование явных конечных автоматов (State Machines) для жизненного циклаCollectors, сессий и миграций. Недопустимые переходы должны быть невозможны на уровне типов. **Apply when**: Управление жизненным циклом сложных компонентов. **Avoid**: Большое количество разрозненных `Bool` флагов для описания состояния. **Verification**: Unit-тесты покрывают матрицу переходов. ## 5. Validated Value Types **Problem**: Проброс примитивов (String, Int) через все слои приводит к потере смысла и ошибкам валидации. **Rule**: Использование отдельных типов-обёрток для доменных понятий (ID, Timestamp, Confidence). Проверка инвариантов происходит при создании типа. **Apply when**: Все доменные сущности и параметры портов. **Avoid**: Использование `String` для ID или `Double` для Confidence без обёртки. **Verification**: Код компилируется только при передаче правильных типов; невозможны "пустые" или некорректные значения. ## 6. Manual Composition Root **Problem**: Глобальные синглтоны и Service Locator делают зависимости неявными. **Rule**: Использование ручного внедрения зависимостей (Constructor Injection) в единственной точке входа (Composition Root). Глобальные мутабельные синглтоны запрещены. **Apply when**: Инициализация приложения в `AppShell`. **Avoid**: Использование `shared` instance для бизнес-логики. **Verification**: Все зависимости можно подменить (mock) в тестах без изменения кода модулей. ## 7. Workflow-Sized Services **Problem**: Use cases, которые делают слишком мало (один метод) или слишком много (весь модуль). **Rule**: Application Service должен отражать осмысленный пользовательский или системный воркфлоу (например, `AssistantSessionService`) и оркестровать несколько портов. **Avoid**: Создание класса UseCase для каждой мелкой функции; "божественные" объекты-координаторы. **Verification**: Сервис покрывает логически связанную группу действий. ## 8. Typed Failure States **Problem**: Обобщённые ошибки `Swift.Error` не дают понимания, как на них реагировать. **Rule**: Ожидаемые ошибки моделируются как типизированные состояния (Enum). Ошибки адаптеров переводятся в доменные ошибки на границе модуля. **Apply when**: Возврат результатов из портов и сервисов. **Avoid**: Проброс `NSError` или `URLError` в доменные слои. **Verification**: UI может точно отобразить причину сбоя на основе типа ошибки. ## 9. Structured Task Ownership **Problem**: Утечки задач (detached tasks) и сложности с отменой (cancellation). **Rule**: Каждая долгоживущая `Task` принадлежит владельцу жизненного цикла и отменяется при его завершении. `Task.detached` запрещён, кроме системных воркеров. **Apply when**: Запуск Collectors и фоновой обработки. **Avoid**: "Fire-and-forget" задачи без сохранения ссылки на отмену. **Verification**: Deinit объекта приводит к остановке всех запущенных им задач. ## 10. Dedicated Executors for Blocking Work **Problem**: Блокировка потока актора или MainActor тяжелыми вычислениями. **Rule**: Все блокирующие операции (SQLite, ML, PCM) выносятся на выделенные очереди или исполнители (Dedicated Executors/Queues). Оркестрация акторов не должна выполнять тяжелую работу. **Apply when**: I/O, обработка медиа, криптография. **Avoid**: Выполнение `Data(contentsOf:)` или сложных циклов на MainActor. **Verification**: Профилирование в Instruments не показывает блокировок UI потока.