Forge
markdowne8ad0934
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
1141. **Domain / model** — `ChatSurfaceEntry`, правила compositor.
1152. **Application** — orchestration, ViewModel-команды (без Skia).
1163. **Presentation** — `SkiaChatMessage`, layout, draw.
1174. **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
1531. **Классический OOA&D + GRASP + итерации:** Craig Larman — *Applying UML and Patterns* («Применение UML и шаблонов проектирования») — **главный якорь** для фундаментального прохода.
1542. **UML как нотация:** Rumbaugh & Blaha — *UML 2.0. Объектно-ориентированное моделирование* (есть в `programming-books-catalog.md`).
1553. **Историческая тройка (опционально):** Booch / Rumbaugh (OMT) / Jacobson (OOSE) — контекст слияния в UML; для агента достаточно п.1–2.
1564. **Паттерны (после GRASP):** Gamma et al. — GoF.
1575. **Сложный домен:** Evans — DDD; Vernon — Implementing DDD.
1586. **Рефакторинг legacy:** Feathers — *Working Effectively with Legacy Code*.
1597. **Практика построения:** 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
View only · write via MCP/CIDE