| 1 | # KB: объектно-ориентированный анализ и проектирование (OOA&D) v1 |
| 2 | |
| 3 | **Назначение:** фундаментальный канон по **OOA&D** и смежным практикам — откуда берётся правило «существительные → сущности, глаголы → методы», как не сводить его к косметическому рефакторингу. |
| 4 | **Операционный сжатый проход для агента:** `playbook-ooad-agent-operational-v1.md`. |
| 5 | **Короткий стоп-кран в коде:** `playbook-domain-nouns-verbs-decomposition-v1.md`. |
| 6 | |
| 7 | **Версия:** v1.0 · 2026-05-17 — первый фундаментальный проход (канон agent-notes KB). |
| 8 | |
| 9 | **Проверено:** концепции стабильны (Larman GRASP, классический noun/verb analysis, UML 2); конкретные издания — сверять с локальной библиотекой (`programming-books-catalog.md`). |
| 10 | |
| 11 | --- |
| 12 | |
| 13 | ## 1. Термины и границы |
| 14 | |
| 15 | | Термин | Смысл | |
| 16 | |--------|--------| |
| 17 | | **OOA** (Object-Oriented **Analysis**) | Понять **предметную область**: понятия, правила, сценарии. Модель **концептуальная** — ещё без привязки к C#/файлам. | |
| 18 | | **OOD** (Object-Oriented **Design**) | Спроектировать **программную** структуру: типы, ответственности, связи, слои — реализуемо в коде. | |
| 19 | | **OOA&D** | Связка: анализ → проектирование → реализация; итеративно, не обязательно «всё нарисовать, потом код». | |
| 20 | | **OOP** | Реализация: классы, интерфейсы, полиморфизм, инкапсуляция. | |
| 21 | | **Доменная модель** | Согласованное множество понятий предметной области и их связей (не «таблицы БД» и не «экраны»). | |
| 22 | |
| 23 | **Не путать:** |
| 24 | |
| 25 | - **GoF-паттерны** — уровень **дизайна** (решения для повторяющихся микропроблем), после того как есть кандидаты в типы. |
| 26 | - **DDD** (Evans) — **стратегический** и **тактический** дизайн сложного домена (bounded context, aggregate, …); опирается на OOA&D, но шире. |
| 27 | - **Clean Architecture / слои** — организация зависимостей; применяется **после** того, как известны основные сущности и сценарии. |
| 28 | - **Рефакторинг** (Fowler) — улучшение **существующего** кода; **задний ход OOA&D** (как chat Skia: домен уже был, presentation — нет). |
| 29 | |
| 30 | --- |
| 31 | |
| 32 | ## 2. Зачем фундаментальный проход (а не только «быстрый патч») |
| 33 | |
| 34 | - **Существительные и глаголы** — не «лайфхак агента», а **классическая техника OOA** (noun/verb analysis → кандидаты в классы и операции). |
| 35 | - Патч в `switch (kind)` закрывает симптом; без анализа **границы понятий** размываются (`Accent`, `ItemKind`, общий record). |
| 36 | - Для UI/renderer тот же проход: **presentation-сущности** (`SkiaChatMessage`, `TopicCard`) — не дубликат домена, а **отображение** доменных понятий (`ChatSurfaceEntry`, …) с собственными `Measure`/`Draw`. |
| 37 | |
| 38 | **Эвристика агента:** если в задаче звучат **имена из предметной области** — сначала OOA&D-проход (хотя бы 5–10 минут списков), потом код. |
| 39 | |
| 40 | --- |
| 41 | |
| 42 | ## 3. Техники анализа (OOA) |
| 43 | |
| 44 | ### 3.1. Сбор словаря предметной области |
| 45 | |
| 46 | - Прочитать запрос пользователя, ADR, snapshot/DTO, UI-метки. |
| 47 | - Выписать **существительные** (устойчивые понятия): *сообщение, тема, уточнение, тред, карточка, сессия, …* |
| 48 | - Выписать **глаголы** (действия): *отправить, открыть, измерить, нарисовать, подтвердить, переключить overview, …* |
| 49 | - Отметить **правила** (не всегда отдельный класс): *«активная тема одна»*, *«main thread помечен ◆»*. |
| 50 | |
| 51 | ### 3.2. Noun phrase analysis (анализ именных групп) |
| 52 | |
| 53 | | Шаг | Действие | |
| 54 | |-----|----------| |
| 55 | | 1 | Каждое **существенное** существительное → **кандидат в класс/тип** (entity, value object, иногда enum). | |
| 56 | | 2 | Исключить **технический шум** (`string`, `int`, `Index`, `Kind`) — не домен. | |
| 57 | | 3 | Синонимы объединить (*ветка* / *тред* / *thread* → один тип). | |
| 58 | | 4 | **Атрибуты** vs **типы**: если понятие имеет собственное поведение или жизненный цикл — отдельный тип; иначе поле (`IsPending` у `Confirmation`, не глобальный флаг). | |
| 59 | |
| 60 | ### 3.3. Verb analysis и сценарии |
| 61 | |
| 62 | | Шаг | Действие | |
| 63 | |-----|----------| |
| 64 | | 1 | Глагол → **операция** (метод) или **use case** (сценарий из нескольких шагов). | |
| 65 | | 2 | Спросить: **какой объект** естественный субъект глагола? (*Message.send*, *Topic.open*, *Confirmation.resolve*). | |
| 66 | | 3 | Если глагол не ложится ни на один объект — **сервис** / **controller** / **оркестратор** (GRASP Controller) — осознанно, не «static Util». | |
| 67 | |
| 68 | ### 3.4. CRC-карточки (Class–Responsibility–Collaboration) |
| 69 | |
| 70 | На карточке (или строке таблицы) для каждого кандидата: |
| 71 | |
| 72 | - **Class** — имя типа. |
| 73 | - **Responsibilities** — 1–3 обязанности (*хранить текст*, *знать pending*). |
| 74 | - **Collaborators** — с кем взаимодействует (*Thread*, *Session*). |
| 75 | |
| 76 | **Правило:** одна карточка — **узкая** ответственность; «God class» виден, когда responsibilities > ~5 без связной темы. |
| 77 | |
| 78 | ### 3.5. Use case / сценарий (кратко) |
| 79 | |
| 80 | - **Актор** + **цель** + **основной поток** (шаги). |
| 81 | - Каждый шаг — сообщение между объектами (задел под sequence diagram). |
| 82 | - Для агента: достаточно **нумерованного списка** из 5–12 шагов перед рефакторингом модуля. |
| 83 | |
| 84 | --- |
| 85 | |
| 86 | ## 4. Проектирование (OOD) |
| 87 | |
| 88 | ### 4.1. От кандидатов к типам |
| 89 | |
| 90 | - **Инкапсуляция:** данные + операции, которые на них опираются — вместе. |
| 91 | - **Полиморфизм:** разное поведение (`Message` vs `Confirmation` vs `TopicCard`) → **разные типы** с общим интерфейсом (`ISkiaChatEntity`), не `switch`. |
| 92 | - **Связи:** ассоциация (ссылка), агрегация (*тред содержит сообщения*), композиция (жизненный цикл части за целым). |
| 93 | |
| 94 | ### 4.2. GRASP (назначение ответственностей) |
| 95 | |
| 96 | Краткая шпаргалка (по Larman / «Применение UML и шаблонов проектирования»): |
| 97 | |
| 98 | | Принцип | Вопрос | Типичное применение | |
| 99 | |---------|--------|---------------------| |
| 100 | | **Information Expert** | Кто знает данные для выполнения задачи? | Логика расчёта layout у сущности, знающей свои строки. | |
| 101 | | **Creator** | Кто создаёт B, если B агрегирует/записывает A? | `SceneBuilder` создаёт `Message` из `ChatSurfaceEntry`. | |
| 102 | | **Controller** | Кто обрабатывает системное событие (UI, HTTP)? | `SkiaChatSurfaceControl` — scroll/hit; не рисует каждый вид. | |
| 103 | | **Low Coupling** | Как уменьшить зависимости? | Control не знает деталей `TopicCard.Draw`. | |
| 104 | | **High Cohesion** | Всё ли в классе про одно? | `SkiaChatBubbleRenderer` — общий bubble, не всё подряд. | |
| 105 | | **Polymorphism** | Зависимость от вариантов через типы? | `ISkiaChatEntity.Draw` вместо `ItemKind`. | |
| 106 | | **Pure Fabrication** | Нужен тип, которого нет в домене? | `SkiaChatLayoutEngine`, `SceneBuilder` — допустимы, если именованы. | |
| 107 | | **Indirection** | Посредник для развязки? | Builder между snapshot и entities. | |
| 108 | | **Protected Variations** | Что будет меняться? | Новый вид карточки → новый тип, не новый `case`. | |
| 109 | |
| 110 | ### 4.3. Слои (после типов) |
| 111 | |
| 112 | Типичная схема для приложения / IDE: |
| 113 | |
| 114 | 1. **Domain / model** — `ChatSurfaceEntry`, правила compositor. |
| 115 | 2. **Application** — orchestration, ViewModel-команды (без Skia). |
| 116 | 3. **Presentation** — `SkiaChatMessage`, layout, draw. |
| 117 | 4. **Infrastructure** — persistence, MCP, файлы. |
| 118 | |
| 119 | **Правило:** зависимости **внутрь** (к domain); presentation зависит от модели отображения, не наоборот. |
| 120 | |
| 121 | --- |
| 122 | |
| 123 | ## 5. Связь с соседними темами |
| 124 | |
| 125 | | Тема | Отношение к OOA&D | |
| 126 | |------|-------------------| |
| 127 | | **Nouns → entities playbook** | Операционное сжатие §3–4 для агента в сессии. | |
| 128 | | **SOLID** | Принципы **качества** классов после назначения ответственностей (SRP ≈ cohesion). | |
| 129 | | **GoF** | Паттерны **внутри** хорошо выделенных ролей (Strategy ≈ Polymorphism). | |
| 130 | | **DDD** | Когда домен **большой**: bounded context, aggregate root, ubiquitous language — поверх OOA&D. | |
| 131 | | **Refactoring** | Когда анализ пропущен — **восстановить** типы через extract class / replace conditional with polymorphism. | |
| 132 | | **HCI / UX** | Не подменяет OOA&D; влияет на **presentation-сущности** и сценарии. | |
| 133 | |
| 134 | --- |
| 135 | |
| 136 | ## 6. Типичные ошибки (в т.ч. у агентов) |
| 137 | |
| 138 | | Ошибка | Симптом | Лечение | |
| 139 | |--------|---------|---------| |
| 140 | | Пропуск анализа | `enum Kind` + рост `switch` | Noun/verb списки, CRC, новые типы | |
| 141 | | Anemic domain | Только DTO, вся логика в service | Перенос поведения к Information Expert | |
| 142 | | God class | Control/ViewModel > 500 строк, всё подряд | Controller + entities + builder | |
| 143 | | Duplicate domain in UI | Те же поля, что в snapshot, но без типов | Presentation types mirroring domain names | |
| 144 | | Pattern-first | «Применим Factory» до списка существительных | Сначала кандидаты, паттерн — если боль повторяется | |
| 145 | | Big design up front only | Диаграммы без итерации | Короткий цикл: модель → код → тест → уточнение | |
| 146 | |
| 147 | --- |
| 148 | |
| 149 | ## 7. Источники и порядок чтения |
| 150 | |
| 151 | ### Канон (рекомендуемый порядок) |
| 152 | |
| 153 | 1. **Классический OOA&D + GRASP + итерации:** Craig Larman — *Applying UML and Patterns* («Применение UML и шаблонов проектирования») — **главный якорь** для фундаментального прохода. |
| 154 | 2. **UML как нотация:** Rumbaugh & Blaha — *UML 2.0. Объектно-ориентированное моделирование* (есть в `programming-books-catalog.md`). |
| 155 | 3. **Историческая тройка (опционально):** Booch / Rumbaugh (OMT) / Jacobson (OOSE) — контекст слияния в UML; для агента достаточно п.1–2. |
| 156 | 4. **Паттерны (после GRASP):** Gamma et al. — GoF. |
| 157 | 5. **Сложный домен:** Evans — DDD; Vernon — Implementing DDD. |
| 158 | 6. **Рефакторинг legacy:** Feathers — *Working Effectively with Legacy Code*. |
| 159 | 7. **Практика построения:** McConnell — *Code Complete* (Track C в `map-engineering-reading-v1.md`). |
| 160 | |
| 161 | ### Официальные / веб |
| 162 | |
| 163 | - Microsoft Learn — [Object-oriented programming](https://learn.microsoft.com/dotnet/csharp/fundamentals/object-oriented-programming) (OOP в C#, не заменяет OOA). |
| 164 | - Framework Design Guidelines — именование и контракты **публичных** API после проектирования. |
| 165 | |
| 166 | --- |
| 167 | |
| 168 | ## 8. Evidence-записи (для `kb-engineering-evidence-v1.md`) |
| 169 | |
| 170 | - **Fact:** Классический OOA использует noun/verb analysis для выделения кандидатов в классы и операции; OOD назначает ответственности (GRASP) и связи перед кодированием. |
| 171 | - **Heuristic:** Не начинать renderer/presenter с дискриминатора `Kind` по видам доменных понятий; каждое устойчивое понятие — тип с операциями или явный подтип полиморфной иерархии. |
| 172 | - **First adoption task:** для новой UI-фичи выписать 10 существительных и 10 глаголов из ADR/кода; сопоставить с типами; только затем править отрисовку. |
| 173 | - **Success criterion:** нет второго `case` по доменному виду в одном renderer; control < ~400 строк оркестрации. |
| 174 | - **Confidence:** high (по инженерной традиции; конкретная фича — medium до проверки в репо). |
| 175 | |
| 176 | --- |
| 177 | |
| 178 | ## 9. Связанные файлы в KB |
| 179 | |
| 180 | | Файл | Роль | |
| 181 | |------|------| |
| 182 | | `playbook-ooad-agent-operational-v1.md` | Пошаговый проход для агента | |
| 183 | | `playbook-domain-nouns-verbs-decomposition-v1.md` | Быстрый контракт в коде | |
| 184 | | `code-writing-principles-v1.md` | C# / стиль после структуры | |
| 185 | | `worlds/software-engineering-evidence/map-engineering-reading-v1.md` | Track C — книги | |
| 186 | | `worlds/software-engineering-evidence/kb-engineering-evidence-v1.md` | Evidence-строки | |
| 187 | |