Именование сущностей в домене: ошибки и решения
Плохое имя сущности превращает доменную модель в набор исключений и комментариев. Разбираем, как отличать сущность от DTO и справочника, проверять названия на границах контекстов и не тащить язык базы данных в бизнес-код.

Сущность с именем Data, Info или Manager редко остаётся безобидной заготовкой: через несколько месяцев в ней оказываются правила разных процессов, а разработчики начинают угадывать смысл полей по месту использования. В этой практике разберём, как называть доменные сущности так, чтобы имя помогало проектировать границы, находить ошибки в модели и не ломалось при росте системы.
Имя сущности — это часть архитектуры
Название не просто делает код читабельнее. Оно фиксирует ответ на вопрос: что именно существует в бизнес-домене и какие правила к этому объекту относятся.
Например, слово Order может означать заказ покупателя, заявку на закупку, поручение на доставку или строку заказа в интеграции с внешней системой. Технически это могут быть четыре класса. В разговоре команды — одно слово. Такая разница быстро превращается в ошибки: разработчик добавляет в заказ оплату, хотя перед ним заявка на закупку, или использует статус доставки в модели, которая описывает только оплату.
Хорошее имя не объясняет, как объект устроен. Оно ограничивает, что в этот объект вообще можно положить.
Четыре ошибки, которые встречаются чаще всего
1. Технические имена вместо доменных
Entity, Record, Model, DataObject и Container описывают форму хранения или роль в фреймворке, но не предметную область. По такому имени невозможно понять, какие операции допустимы и кто владеет правилами.
Если объект хранит данные о человеке, уточните его роль: Customer, Employee, Supplier или Passenger. Эти слова могут ссылаться на одну физическую персону, но описывают разные отношения с системой. Объединять их только потому, что у них совпадают имя и телефон, опасно.
2. Одно имя для разных смыслов
Типичный пример — Client. Для отдела продаж это потенциальный покупатель, для поддержки — владелец обращения, для биллинга — плательщик. У этих объектов разные жизненные циклы, обязательные поля и права доступа.
Если сущность имеет разные правила в разных частях продукта, сначала проверьте, не смешаны ли контексты. Иногда правильные имена будут такими: Lead, AccountHolder и SupportRequester. Это не избыточность, а явная фиксация разных смыслов.
3. Название по текущему экрану
CheckoutForm, SettingsPage и OrderRow уместны на уровне интерфейса или транспорта. Но если их используют как доменные сущности, UI начинает диктовать бизнес-модель. После появления мобильного приложения, импорта или фоновой обработки такие имена становятся ложными.
Разделяйте объект ввода и объект предметной области. Форма оформления заказа может называться CheckoutRequest, а созданная в результате сущность — Order. Они связаны, но не обязаны иметь одинаковые поля.
4. Сокращения и слова без границ
Usr, Cust, Txn и Cfg экономят несколько символов, но добавляют время на чтение и риск разных трактовок. Особенно дорого обходятся сокращения в интеграциях: разные команды начинают расшифровывать их по-разному.
Осторожнее и со словами вроде Status, Type, Info и Data. Они допустимы как часть точного имени — например, PaymentStatus, — но редко работают самостоятельно.
Как выбирать имя: рабочий процесс
- Опишите событие, в котором объект участвует. Не «у нас есть клиент», а «человек отправил заявку», «организация оплатила счёт» или «оператор назначил доставку». Проверка: команда может одним предложением сказать, зачем объект существует.
- Назовите роль объекта в этом событии. Один и тот же человек может быть покупателем, получателем и плательщиком. Проверка: имя отвечает на вопрос «кто или что действует в этом процессе», а не только «какие у объекта поля».
- Отделите сущность от значения и документа. Сущность сохраняет идентичность во времени, объект-значение описывает характеристику, а DTO переносит данные между слоями. Проверка: вы можете объяснить, что изменится при смене значения и что должно остаться тем же объектом.
- Проверьте глаголы. Сущность должна участвовать в понятных операциях:
approve,cancel,assign,reserve. Если единственные операции — «заполнить поле» и «сохранить», возможно, перед вами структура данных, а не доменная сущность. Проверка: у объекта есть хотя бы одно правило, которое нельзя безопасно выразить простым присваиванием. - Проговорите имя вне кода. Попросите аналитика, тестировщика и владельца процесса описать объект без классов и таблиц. Проверка: они используют одно и то же слово или явно называют разные значения.
- Проверьте имя на будущем сценарии. Добавьте мысленно импорт, повторную обработку, отмену и второй канал продаж. Проверка: название не привязано к конкретному экрану, базе или текущей интеграции.
Как не перепутать сущность, DTO и объект-значение
Эти роли часто получают одинаковые имена, хотя у них разная ответственность. Проблема проявляется, когда транспортный объект начинают передавать глубоко в доменную логику: бизнес-правила начинают зависеть от JSON, названий колонок и особенностей конкретного API.
| Тип объекта | Что выражает | Как называть | Чего избегать |
|---|---|---|---|
| Сущность | Объект с идентичностью и жизненным циклом | Customer, Subscription, Shipment | Model, Record, Data |
| Объект-значение | Характеристику, важную целиком | Money, Address, DateRange | AddressData, ValueObjectBase |
| DTO | Формат передачи между границами | CreateShipmentRequest, CustomerResponse | Использовать DTO как доменную модель |
| Справочное значение | Код или набор разрешённых вариантов | PaymentMethod, DeliveryZone | UniversalType, Lookup |
Сноска. Объект-значение — объект без собственной идентичности: два значения считаются одинаковыми, если совпадают все их значимые свойства. Например, для адреса важен состав адресных компонентов, а не отдельный внутренний идентификатор записи.
Три подхода к именованию и их цена
В команде обычно сталкиваются не «правильное» и «неправильное» имя, а разные стратегии. Важно выбрать одну осознанно и понимать, чем она оплачивается.
| Подход | Когда полезен | Плюс | Цена |
|---|---|---|---|
| Термины бизнеса | Домен хорошо понятен участникам процесса | Код совпадает с разговором команды | Нужно отдельно уточнять омонимы |
| Имя плюс контекст | Одно слово имеет несколько значений | Смысл виден прямо в типе | Названия становятся длиннее |
| Техническая нейтральность | Интеграционный или инфраструктурный слой | Проще менять бизнес-термины на границе | Внутри домена быстро теряется смысл |
| Имена по командам | Большая система с автономными подсистемами | Каждый контекст получает собственную модель | Нужны явные преобразования между моделями |
На практике чаще всего работает комбинация: язык бизнеса внутри контекста, уточняющий префикс или суффикс при омонимии, технические названия только на границах хранения и транспорта.
Что ломается при переименовании
Имя меняют, а смысл оставляют прежним
Переименование Client в Customer не исправит модель, если в ней по-прежнему живут правила поставщика и получателя. Сначала составьте список сценариев и владельцев правил, затем решите, один ли это объект. Иначе команда получит красивое имя поверх прежней путаницы.
База данных диктует домен
Таблица orders не доказывает, что доменный объект обязан называться Order. В базе может быть техническая запись, журнал изменений или денормализованная проекция. Не переносите название таблицы в код без проверки её бизнес-смысла.
Локализация создаёт два словаря
Не переводите термины механически. Если бизнес использует «заказ», а команда называет тот же объект Purchase, зафиксируйте решение в словаре проекта. Особенно опасны пары «заказ — покупка», «клиент — пользователь» и «оплата — платёж»: в конкретной системе они могут быть разными объектами.
Когда какое решение выбирать
- Если термин однозначен для всех участников процесса, используйте его без технических добавок.
- Если термин повторяется в нескольких смыслах, добавьте контекст:
BillingCustomerиSupportCustomerлучше, чем один универсальныйCustomer. - Если объект пересекает границы сервисов или команд, не пытайтесь сохранить один класс для всех случаев. Перевод между моделями дешевле скрытых исключений.
- Если объект нужен только для HTTP, очереди или SQL, назовите его по формату и операции:
ImportRow,UpdateProfileRequest,ShipmentProjection.
Что делать дальше
Возьмите пять самых спорных классов и составьте для каждого карточку: имя, бизнес-сценарии, владелец правил, граница контекста и похожие термины. Затем проверьте поиск по репозиторию: если одно имя встречается в контроллерах, миграциях, фоновых задачах и отчётах с разными смыслами, это кандидат на разделение.
После переименований измеряйте не количество изменённых файлов, а число исключений в коде, преобразований между слоями и вопросов на ревью. Следующий полезный шаг — словарь домена в репозитории с примерами «используем» и «не используем». Он дешевле большой миграции и показывает, выдерживает ли выбранная модель реальную работу команды.
Грант-менеджер: Заявки на ФСИ, Сколково, «Мой бизнес» — бюрократическим языком, со сметой.
Спросить за 20 ₽Источники: Domain Model — Martin Fowler, Ubiquitous Language — Martin Fowler
Частые вопросы
Нужно ли называть класс так же, как таблицу в базе данных?
Что делать, если бизнес использует одно слово для разных объектов?
Стоит ли переименовывать плохую сущность в большом проекте?
Что делать, если после переименования ничего не стало понятнее?
Имеет ли значение версия языка или фреймворка?
Можно ли использовать русские бизнес-термины в именах классов и полей?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.