MAPPER — модель кода и предметная область
MAPPER — Model: Abstract Partial and Programmable Explaining Reality (модель: абстрактная, частичная, программируемая, объясняющая реальность). Это правило проектирования: код — модель реальности, а не набор технических деталей без связи с предметной областью.
Статья — мост между культурой именования и стиля и доменной моделью. Дальше: анемичные модели и примитивы, указатель тем.
Зачем нужна явная модель
Программа всегда описывает упрощённый срез мира: вы не кодируете физику Вселенной, а только то, что нужно для задачи (заказ, платёж, маршрут робота). Ошибка начинается, когда в коде появляются сущности, которых нет в предметной области, или одна реальная вещь размазана по десяти string и int.
| Критерий MAPPER | Смысл для разработчика |
|---|---|
| Model (модель) | Есть осознанная картина домена, а не «поля как в таблице БД» |
| Abstract (абстрактная) | Детали скрыты; снаружи видны операции и инварианты |
| Partial (частичная) | Моделируем только нужные аспекты, без лишнего |
| Programmable (программируемая) | Поведение выражено в коде, а не в голове одного автора |
| Explaining Reality | Имена и границы объектов узнаваемы экспертом предметной области |
Петер Наур формулировал близкую мысль: программа — это теория о части мира, которую вы автоматизируете. MAPPER делает эту теорию проверяемой на ревью: «есть ли в коде лишний объект?», «не размазали ли мы Invoice по трём сервисам?».
Биекция «реальность ↔ код»
Идеальная (и недостижимая на 100 %) цель — биекция: каждому значимому понятию в домене соответствует один явный элемент модели (класс, тип, модуль), и наоборот.
// Слабая модель: «деньги» размазаны по примитивам
void Charge(decimal amount, string currencyCode) { ... }
// Ближе к MAPPER: деньги — объект предметной области
void Charge(Money total) { ... }
Нарушение биекции — частый источник запахов:
- примитивная одержимость —
string email,double latitudeвместоEmail,GeoPoint(статья 6, 4-02/616); - анемичные модели — класс
Orderтолько с геттерами, вся логика вOrderService; - лишние
ifиnull— вместо явного состояния или Null Object (статья 8); - глобалы и синглтоны — «объект есть в коде», но в реальности так не устроено (статья 9).
MAPPER не заменяет доменную модель и чистую архитектуру, а задаёт критерий качества кода внутри домена: сущности и value object должны быть узнаваемы аналитиком и тестируемы без «магии» в утилитах.
Единственный принцип проектирования программ
На практике все остальные практики чистого кода сводятся к установке: сопоставляйте реальные сущности с проектом в масштабе один к одному (насколько это возможно в выбранной парадигме).
- Сначала поведение и границы — что объект делает и что запрещено; имена — потом (культура имён).
- Один уровень абстракции в методе — читатель не переключается между «бизнесом» и «SQL/JSON» в одной функции.
- Явные предусловия — неверные комбинации отсекаются рано (быстрый провал).
- Рефакторинг от запаха к модели — не «переименовать переменную», а «найти недостающий объект» (см. методы рефакторинга).
Частичность и объяснимость
Модель намеренно неполная. Для интернет-магазина не нужен класс CustomerDNA; для расчёта скидки не нужна полная история кликов. Частичность — это дисциплина: не тащить в код понятия «на будущее» (YAGNI).
Explaining Reality — проверка с экспертом или с тестом:
- «Что в системе называется Reservation?»
- «Где живёт правило отмены брони — в одном месте или в пяти
if?»
Если объяснение требует схемы из двадцати стрелок между сервисами, модель в коде, скорее всего, разъехалась с реальностью.
MAPPER и ИИ-генерация кода
Модели выдают объёмный, правдоподобный текст, который легко нарушает биекцию (лишние хелперы, дубли, null, глубокие if). MAPPER — чек-лист ревьюера:
- каждый новый класс — кто в домене?
- можно ли заменить пачку флагов одним объектом состояния?
- тест фиксирует поведение, а не «снимок» сгенерированного шума?
Мини-практикум на ревью
| Вопрос | Плохой знак | Куда смотреть |
|---|---|---|
| Сколько «сущностей» в задаче на словах? | В коде их вдвое больше или меньше | 6, 13 |
| Где правило X? | В Utils, Manager, Helper | 1 |
| Что при невалидных данных? | null, тихий return | 8, 10 |
| Меняется ли смысл при рефакторинге? | В одном PR и фича, и перестройка | 10, легаси |
См. также
- M. Fowler — рефакторинг
- R. Martin — чистая архитектура
- Указатель тем раздела
Дальше: Анемичные модели и примитивы → Условия, null и контракты.
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Именование, форматирование, комментарии, документация в коде и базовые принципы читаемости — практики, которые команда договаривается соблюдать каждый день. Цикломатическая сложность — одна из наиболее устойчиво применяемых метрик статического анализа программного кода, призванная количественно оценивать логическую структуру исполняемого модуля. Богатые объекты предметной области, value objects вместо string/int и антипаттерны DTO-оргии. const, иммутабельность, ленивая инициализация и побочные эффекты в читаемом коде. Разделение «что» и «как», итерации, магические числа, callback hell и явные ошибки. Меньше if и switch, отказ от null, быстрый провал и полиморфизм вместо флагов. Singleton, god object, shotgun surgery, feature envy и глобальное состояние — симптомы и приёмы рефакторинга. Мёртвый код, лишние абстракции, отключённые предупреждения и отложенный рефакторинг. Приватные методы, flaky-тесты, assertTrue, моки и данные — качество тестового кода и связь с разделом тестирования. Пустые catch, исключения как goto, узкие try и сообщения для пользователя. Краткие итоги раздела "Культура кода". Вопросы перед отправкой кода в репозиторий — именование, принципы, тесты, ревью и безопасность. Ответы ищите в статьях раздела.Культура написания и поддержки кода
Цикломатическая сложность и читаемость кода
Анемичные модели и примитивная одержимость
Изменяемость, побочные эффекты и неизменяемые данные
Декларативный код — что и как
Условия, null и явные контракты
Связанность, глобалы и запахи модульности
YAGNI, быстрый провал и техдолг в коде
Тесты как часть культуры кода
Исключения и обработка ошибок в читаемом коде
Итоги
Чек-лист самопроверки