BI Consult Desktop Logo BI Consult Mobile Logo
  • Russian BI Исследование российских bi
  • Перейти на Fine BI
  • Контакты
  • +7 812 334-08-01
    +7 499 608-13-06
  • Отправить сообщение
  • Главная
  • Продукты Эксперт-BI
    • Дистрибуция
    • Розничная торговля
    • Производство
    • Операторы связи
    • Страхование
    • Банки
    • Лизинг
    • Логистика
    • Нефтегазовый сектор
    • Медицина
    • Сеть ресторанов
    • E-Commerce
    • Сельское хозяйство
    • Энергетика
    • FMCG
    • Девелоперы
    • Маркетплейсы
    • Пищевая промышленность
    • Фармацевтика
    • Построение Data Platform
    • Цифровая трансформация
    • Управление по KPI
    • Финансы
    • Продажи
    • Склад
    • HR
    • Маркетинг
    • Внутренний аудит
    • Категорийный менеджмент
    • S&OP и FP&A
    • Геоаналитика
    • Цепочки поставок (SCM)
    • AutoML
    • Process Mining
    • IBP
    • ИТ (CIO)
    • Закупки
  • Платформы
    • Системы бизнес-анализа (BI)
    • Интегрированное бизнес-планирование (IBP)
    • Хранилища данных (DWH / Lakehouse)
    • Каталоги данных (Data Catalog)
    • Системы ETL и ELT
    • AI / Исскуственный интеллект
    • Шина данных (ESB)
    • Система управления мастер-данными (MDM)
    • Семантический слой
  • Услуги
    • Переход на отечественные BI и DWH системы
    • Консалтинг
    • Пилотный проект
    • Обучение и сертификация
    • Бесплатное обучение
    • Поддержка
    • Технические задания
    • Сбор требований для проекта внедрения BI-системы
    • CI/CD для DWH
    • Аудит BI приложений и DWH
    • Выделенная команда
    • Настойка и поддержка баз данных
    • Разработка BI Стратегии
    • Styleguide для BI-системы
    • Как выбрать BI-систему
  • Курсы
    • Учебный курс Информационная грамотность (Data Literacy)
    • Учебный курс для бизнес-аналитиков
    • Учебный курс для системных аналитиков
    • Учебный курс по Data Governance
    • Учебный курс Как стать CDO
    • Учебный курс Современная архитектура хранилища данных
    • Учебный курс по Fine BI
    • Учебный курс по FineReport
    • Учебный курс по DWH
    • Учебный курс по Data Science (ML, AI)
    • Учебный курс по PostgreSQL
    • Учебный курс по Greenplum
    • Учебный курс по Apache Airflow и NiFi
    • Учебный курс по Open-source BI
    • Учебный курс по ClickHouse
    • Учебный курс по DataLens
    • Учебный курс по Loginom
    • Учебный курс по Modus BI и ETL
    • Учебный курс по Visiology
    • Учебный курс по dbt (Data Build Tool)
  • Компания
    • Руководство
    • Новости
    • Клиенты
    • Карьера
    • Скачать
    • Контакты

BI

  • FineBI
  • FineReport
  • FineDataLink
  • FineChatBI (FineAI)
  • Коннекторы данных из 1С в BI
  • Airflow / Nifi
  • Visiology
  • PIX BI
  • Modus BI
  • Yandex.DataLens
  • Open-source BI: Superset/Metabase
  • Luxms BI
  • AW BI + Alpha BI
  • FlyBI + Форсайт. Аналитическая Платформа
  • Loginom
  • Триафлай
  • AI / Исскуственный интеллект
  • Optimacros
  • Навигатор BI
  • Семантический слой

СУБД

  • Arenadata
  • ClickHouse
  • Greenplum
  • Postgres Professional
  • TData

Другое

  • Построение Data Platform
    • Аналитическое хранилище данных
    • Data Lake и Data Engineering
    • Подробнее про Data Lake
    • Внедрение Lakehouse
      • Apache Doris
      • StarRocks
      • Trino
    • Миграция витрин из пропиетарных DWH на новый стек
    • Учебный курс "Современная архитектура хранилища данных"
Главная » Курсы по системам бизнес-анализа и методологии » Учебный курс Современная архитектура хранилища данных » Domain-Driven Design (DDD): понятия, контексты и пример » Значения объектов и доменные типы: правила моделирования

Значения объектов и доменные типы: правила моделирования

Значения объектов и доменные типы являются краеугольными кирпичами качественной доменной модели. Они позволяют формализовать концепции, которые не обладают собственной идентичностью, но несут смысловую нагрузку в рамках бизнес-правил. В рамках Domain-Driven Design такие конструкции служат для точного выражения доменной семантики, снижения связности между контекстами и упрощения эволюции модели при изменениях бизнес-требований. Правильное моделирование значений объектов обеспечивает устойчивость архитектуры к изменениям, повышает читабельность кода и упрощает коммуникацию внутри команды благодаря единому Употреблению языка домена (Ubiquitous Language).

Здесь следует четко различать сущности, значения объектов и доменные типы. Сущности опираются на идентичность: их существование отслеживает «кто» и «когда» изменялся. Значения объектов обременены семантикой и неизменяемостью: две сущности могут быть одинаковыми по смыслу, если их значения совпадают. Доменные типы - это обобщенные конструкции, которые encapsulate доменную логику и правила валидности для конкретной предметной области, часто используемые как составные части внутри агрегатов.

Ключевой мотив моделирования значений объектов - выражение бизнес-правил на первом параграфе кода. Это позволяет не только держать invariants в рамках границ агрегатов, но и снижает риск нарушения консистентности при изменении слоев архитектуры или при интеграции с внешними системами. В контексте Bounded Context значение объектов становится средством коммуникации между командой домена и инфраструктурой через хорошо определенные контракты и канонические формы данных.

  • Краткое содержание главы
  • Отличие значений объектов от сущностей и роле доменных типов в модели
  • Правила проектирования и реализации неизменяемых значений объектов
  • Инварианты, фабрики и валидаторы: как сохранять целостность доменной логики
  • Примеры реализации и применение в архитектуре окна контекстов

     

Что такое значения объектов и доменные типы: концепции

Значение объектов (Value Objects) - это объекты без собственной идентичности, определяемые только своей семантикой и состоянием. Их основная роль - выражение концепций домена и инвариантов, которые не требуют отдельной идентификации в системе. Признаки Value Objects: неизменяемость, идентичность по значению, отсутствие побочных эффектов. Набор атрибутов внутри Value Object полностью описывает его состояние; если состояние совпадает, объекты считаются равными.

Доменные типы (Domain Types) - это типы данных, обертывающие бизнес-правила и специфику предметной области. Они являются абстракциями над примитивами, но с инкапсулированной логикой валидации, форматирования и преобразований. Часто доменные типы реализуются как Value Objects и применяются внутри агрегатов для обеспечения целостности invariant’ов и единообразия Ubiquitous Language.

В контексте архитектурной практики значение объекта следует рассматривать как структурную единицу внутри агрегата: она может состоять из нескольких полей и быть составной частью более крупных значений. С точки зрения дизайна, они должны быть малы, семантически ясны и легко тестируемы. При этом они не должны содержать зависимости на внешние состояния или поведение сущности за пределами своей ответственности.

Зачем это важно для стратегического проектирования? Значения объектов выступают амортизаторами изменений: они ограничивают область, в которой бизнес-правило распространяется, и служат «языком домена» внутри команды. Взаимодействия между контекстами через интеграционные контракты и DTO-графы часто опираются на значения объектов как на канонический формат передачи данных, что упрощает управление изменениями и снижает риски изоляции контекстов.

 

Правила моделирования значений объектов

Здесь приведены базовые, но критически важные принципы для проектирования и внедрения значений объектов в вашем дизайне на уровне архитектуры и кода.

  • Неизменяемость по умолчанию. Значения объектов должны создаваться с фиксированным состоянием и не изменять его впоследствии. Любые операции над ними возвращают новый экземпляр, а не мутируют существующий. Это минимизирует рикошет изменений и упрощает параллелизм и кэширование.

  • Равенство по значению. Смысловое равенство Value Object определяется полями, а не идентификатором. Важно переопределять Equals и GetHashCode (или эквивалентные механизмы в выбранном языке) так, чтобы две объекты считались равными, если у них совпадают все данные.

  • Инварианты на этапе создания. Валидация должна выполняться на фабрике создания Value Object. Непосредственно в геттеры не должны попадать side-effect’ы или исключения. Фабрика должна либо возвращать успешно созданный объект, либо бросать понятное исключение, отражающее нарушение бизнес-правила.

  • Малость и когезия. Value Object должен быть малым и сфокусированным; если он становится слишком сложным, его следует разделить на несколько меньших Value Objects или обернуть внутри другого доменного типа. Это облегчает сопровождение и повторное использование.

  • Инкапсуляция валидности и форматирования. Внутри Value Object размещайте логику валидации форматов, единиц измерения, нормализации и представления значения. Это обеспечивает единое место ответственности и упрощает адаптацию к изменениям в бизнес-правилах.

  • Контракты и интеграции. При передачах между контекстами используйте канонические формы данных; избегайте передачи «живых» доменных объектов между границами контекстов. Применяйте анти-подслой (Anti-Corruption Layer), преобразуя доменные типы в унифицированные DTO для потребителей из другого Bound Context.

  • Композиция через другие Value Objects. Значения объектов можно и стоит строить из более простых Value Objects (напр., Money может состоять из Amount и Currency; Address может включать Street, City, PostalCode). Это упрощает тестирование и повторное использование.

  • Поведение как метод общения, а не поле. Любые операции (например, сложение Money, сравнение двух адресов) должны возвращать новые Value Objects или результаты операций, но не менять внутреннее состояние. Это поддерживает функциональный стиль и позволяет легко рассуждать о ходе выполнения бизнес-логики.

  • Очистка границ контекста. Значения объектов часто применяются внутри агрегатов для выражения бизнес-правил. Они помогают локализовать ответственность, но не должны приводить к чрезмерной связанности между агрегатами или контекстами.

  • Тестирование как встроенная практика. Тесты на Value Objects чаще всего просты и детерминированы: тестируют корректность равенства, валидацию на создание, поведение операций и устойчивость к граничным условиям.

     

Доменные типы vs сущности и агрегаты

Различие между доменными типами и сущностями становится очевидным при анализе контекста и границ. В сущности идентичность - ключевой фактор: два экземпляра могут обладать одинаковыми данными, но они различаются по своей жизненной истории и идентификатору. Value Object и Domain Type не требуют идентичности; они существуют ради семантики и invariants.

Агрегаты оборачивают набор связанных объектов и обеспечивают целостность на уровне границ. Внутри агрегата Value Objects поддерживают инварианты и формируют единое целое, которое может быть валидировано и обрабатываться как единое целое. Взаимодействия между агрегатами происходят через интеграционные контракты, которые обычно реализованы через DTO/передаваемые структуры, отражающие каноническую модель данных. Диапазон изменений языка между контекстами минимизируется за счет использования устойчивых доменных типов и явного маппинга.

Границы между контекстами следует проектировать так, чтобы ключевые invariants не пересекались напрямую через границы. В идеале каждый контекст имеет собственные адаптеры и конвенции именования. Для сложных бизнес-процессов возможно применение общего канона, однако это требует тяжелого согласования и соответствующих механизмов версионирования контрактов.

 

Инварианты, валидаторы, правила формирования и интеграционные контракты

Психологически и технически инварианты - это фундаментальные правила доменной модели, которые должны выдерживать любые входящие изменения и эволюцию. Инварианты могут охватывать ограничение на значения атрибутов Value Object, сопоставление полей внутри агрегатов или условия согласованности между несколькими доменными типами.

  • Инварианты создания. Все Value Object создаются через фабрики (factory methods) или конструкторы с валидной бизнес-логикой. Это препятствует созданию «полувалидных» состояний и упрощает раннее обнаружение ошибок.

  • Валидация в фабриках. Валидаторы должны быть настроены так, чтобы ошибки в переданных данных возвращали понятные сообщения бизнес-уровня. Избегайте возвращения null; применяйте либо исключения, либо Result-объекты, возвращающие статус и сообщение об ошибке.

  • Гарантии иммутабельности. Любые операции, которые должны менять значения, создают новый экземпляр Value Object. Это упрощает многопоточность и снижает риск гонок данных.

  • Интеграционные контракты. При взаимодействии между Bound Contexts внешние границы должны получать данные через заранее определенные DTO, представляющие каноническую форму доменных типов. Прекращайте «экспорт» внутренних правд домена в формате, который может быть неверно интерпретирован другой командой. В случае изменений контракта применяйте версионирование и агенты трансформации.

  • Анти-подслой (Anti-Corruption Layer). При взаимодействии с внешними системами или контекстами используйте адаптеры, которые переводят данные в и из доменной модели. Это позволяет сохранит чистоту внутренней доменной логики и снижает зависимость от внешних изменений.

  • Валидаторы и тесты. Включайте тесты на инварианты создания и поведение операций над Value Objects. Тестирование помогает выявлять нарушения бизнес-правил на ранних стадиях и облегчает рефакторинг.

  • Оптимизация и сериализация. Обеспечьте стабильную сериализацию Value Objects, полезную для хранения и передачи. Определяйте согласованные форматы представления (например, для Money - Amount и Currency) и избегайте полей, зависящих от сессии или внешних состояний.

     

Практические примеры реализации в архитектуре и коде

Ниже приводятся примеры типичных Value Objects, которые часто встречаются в доменной модели: Money и Address. Реализация ориентирована на архитектуру, где Value Objects являются неизменяемыми и сравниваются по значению. Приведены упрощенные примеры на языке C#, иллюстрирующие принципы immutability, корректной семантики равенства и корректной обработки единиц измерения.

// Money value object
public sealed class Money : IEquatable
{
    public decimal Amount { get; }
    public string Currency { get; }

    private Money(decimal amount, string currency)
    {
        Amount = amount;
        Currency = currency;
    }

    public static Money Of(decimal amount, string currency)
    {
        if (amount  Equals(obj as Money);
    public bool Equals(Money other) => other != null && Amount == other.Amount && Currency == other.Currency;
    public override int GetHashCode() => HashCode.Combine(Amount, Currency);

    public static bool operator ==(Money left, Money right) => Equals(left, right);
    public static bool operator !=(Money left, Money right) => !Equals(left, right);
}
// Address value object (record для неизменяемости)
public record Address(string Street, string City, string PostalCode);

В реальном проекте кода следовало бы добавить дополнительные сервисы валидации, например, нормализацию посткодов, правила форматирования, региональные требования (например, для конкретной страны). Однако базовый подход остаётся универсальным: Value Objects должны быть простыми, предсказуемыми и безопасными в многопоточном окружении. В практике архитектуры это приводит к тому, что:

  • операции над агрегатами становятся выразительнее: изменение состояния агрегата через Value Objects приводит к понятной и устойчивой логике;
  • маппинг между контекстами становится чистым: внешние контракты отражают каноническую форму данных (как в Money - Amount и Currency), что упрощает интеграцию;
  • тестирование становится прямолинейным: тестируются равенство, создание и бизнес-правила на уровне Value Objects, а не на уровне сложных объектов.

Важно помнить, что значение объектов и доменные типы не заменяют сущности и агрегаты - они дополняют их. В рамках архитектуры они служат для выражения бизнес-правил и поддержания целостности внутри предметной области, особенно в границах контекстов, где самостоятельные изменения легче адаптировать без разрушения всей системы.

Другие примеры доменных типов, часто используемых в системах, включают:

  • Email, PostalCode, PhoneNumber как Value Objects с валидацией форматов;
  • Period, DateRange как композиции, отражающие временные invariants;
  • Quantity, Percentage как числа с ограничениями на диапазоны и единицы измерения.

Эти примеры демонстрируют, как доменные типы позволяют формально выразить нормы и правила без «распыления» бизнес-логики по множеству классов, что обеспечивает единообразие, предсказуемость и более безопасную эволюцию модели.

 

Key takeaways

  • Значения объектов - это неизменяемые структуры, определяемые по значению, а не по идентичности; они снижают риск ошибок и упрощают параллелизм.
  • Доменные типы инкапсулируют бизнес-правила и валидацию, служа строительными блоками для конкретной бизнес-логики внутри Bound Context.
  • Правильное моделирование требует фабрик для создания, чистой валидности на входе и строгого разделения обязанностей между Value Objects и сущностями.
  • Взаимодействие между контекстами следует проектировать через устойчивые канонические формы данных и Anti-Corruption Layer, чтобы минимизировать влияние изменений в одной части системы на другие контексты.
  • В архитектуре Value Objects применяются внутри агрегатов для выражения invariants и обеспечения целостности, а cross-context взаимодействия - через DTO и маппинг.
  • Примеры кода демонстрируют принципы: неизменяемость, семантику равенства по значению и безопасные операции, которые возвращают новые экземпляры.
  • Тестирование Value Objects должно быть прямолинейным и сфокусированным на равенстве, создании и валидности, что снижает риск регрессий при изменении бизнес-правил.

     

FAQ

  1. Что такое Value Object и чем он отличается от Domain Type?

Value Object - это объект без собственной идентичности, определяемый исключительно своим состоянием и семантикой; он неизменяем, равенство определяется по значениям полей. Domain Type - это обобщенная конструкция, которая инкапсулирует бизнес-правило и логику в рамках конкретной предметной области, часто реализуемая как Value Object или оборачивающий класс над примитивами. В практике Domain Type служит шаблоном для повторного использования и единообразия используемых данных внутри доменной модели.

 

  1. Зачем нужна неизменяемость Value Object’ов?

Неизменяемость обеспечивает предсказуемость поведения объекта: состояние не изменяется после создания; любые изменения требуют создания нового объекта. Это упрощает reasoning о коде, облегчает параллелизм и делает тестирование проще, поскольку исключаются скрытые побочные эффекты.

 

  1. Как правильно реализовать равенство Value Object’ов?

Равенство следует реализовывать через сравнение всех значений полей, которые составляют объект. Переопределите Equals и GetHashCode (или используйте язык, поддерживающий record/immutability) и предоставьте операторы сравнения, чтобы две инстанции считались равными, если их состояние идентично.

 

  1. Можно ли изменять Value Object после создания?

Нет. Основной принцип - неизменяемость. Любое изменение приводит к созданию нового экземпляра. Это снижает риск непреднамеренных изменений и упрощает поддержку.

 

  1. Как валидировать создание Value Object?

Создание должно происходить через фабрику или конструктор с контролируемыми проверками. Валидатор должен возвращать либо успешно созданный объект, либо информировать об ошибке через понятное сообщение. Непосредственное использование класса без проверки должно быть исключено.

 

  1. Как Vale Object взаимодействуют внутри агрегатов?

Value Objects внутри агрегатов выступают как инвариантные части. Они помогают сохранять консистентность и единообразие бизнес-правил внутри границ агрегата. Любая операция над агрегатом должна приводить к состоянию, где invariants Value Objects сохраняются в валидной форме.

 

  1. Какие подходы рекомендуются при интеграции между контекстами?

Используйте Anti-Corruption Layer и DTO, чтобы передавать каноническую форму данных между контекстами. Не допускайте передачи «живых» доменных объектов между контекстами; при необходимости выполняйте маппинг на уровнях адаптеров или сервисов преобразования.

 

  1. Как тестировать Value Objects?

Тестируйте создание, равенство и базовую логику операций (например, Addition для Money, если она разрешена бизнес-правилами). Важно проверить граничные случаи (нулевые/отрицательные значения, несовместимые валюты) и устойчивость к ошибочному вводу.

 

  1. Можно ли использовать Value Objects в базе данных?

Да, но их хранение чаще всего происходит через их сериализованный вид или через отдельные колонки primitives (например, Money - две колонки: Amount и Currency). Важно сохранять целостность на уровне доменной логики и обеспечивать корректную десериализацию при чтении.

 

  1. Какие риски связаны с неправильным моделированием значений объектов?

Главные риски - избыточная связь между контекстами, смешение обязанностей и нарушение инвариантов из-за неверной ответственности. Плохая реализация может привести к сложной цепочке маппингов и потере бизнес-смысловой цели моделей. Систематический подход к инвариантам, тестированию и четким границам контекстов минимизирует эти риски.

 

← Предыдущая статья
Агрегаты и консистентность: границы транзакций и управление целостностью
Следующая статья →
Репозитории, фабрики и доменные сервисы

 

Узнать стоимость решенияЗапросить видео презентацию

Решения

Анализировать ФинансыУвеличивайте ПродажиОптимальный Склад и ЛогистикаМаркетинговые Метрики

Клиенты
  • Нашей компанией был реализован проект автоматизации конвейера данных на базе СПО ETL-инструмента Apache NiFi для клиента ООО «Императорский Монетный Двор» в части актуализации данных, передаваемых из Системы Oracle в Anaplan.

  • Компания ООО "Комус" - один из лидеров российского рынка оптовых продаж офисных товаров и техники. Компания поставляет широкий ассортимент продукции - от канцелярских принадлежностей до компьютерной техники и офисной мебели.

  • ПАО «Ростелеком» — российский провайдер цифровых услуг и сервисов. Предоставляет услуги широкополосного доступа в Интернет, интерактивного телевидения, сотовой связи, местной и дальней телефонной связи и др. Занимает лидирующие позиции на российском рынке высокоскоростного доступа в интернет, платного ТВ, хранения и обработки данных, а также кибербезопасности

  • Банк "Санкт-Петербург" - это универсальный коммерческий банк, предоставляющий полный спектр финансовых услуг для частных и корпоративных клиентов. Банк основан в 1990 году и имеет генеральную лицензию Банка России на осуществление банковских операций. Сеть банка включает более 170 офисов и отделений, а также свыше 1000 банкоматов и терминалов в Санкт-Петербурге, Москве и других регионах.

  • Решения
    • Дистрибуция
    • Розничная торговля
    • Производство
    • Операторы связи
    • Страхование
    • Банки
    • Лизинг
    • Логистика
    • Нефтегазовый сектор
    • Медицина
    • Сеть ресторанов
    • E-Commerce
    • Энергетика
    • Фармацевтика
  • Услуги
    • Переход на отечественные BI и DWH
    • Консалтинг
    • Пилотный проект
    • Обучение и сертификация
    • Бесплатное обучение
    • Техническая поддержка
    • Технические задания
    • Сбор требований для проекта внедрения BI-системы
    • CI/CD для DWH
    • Аудит BI приложений
    • Выделенная команда
    • Настойка и поддержка баз данных
    • Разработка BI Стратегии
    • Styleguide для BI-системы
    • Как выбрать BI-систему
  • Платформы
    • FineBI
    • FineReport
    • FineDataLink
    • Коннекторы данных из 1С в BI
    • Airflow + NiFi
    • Visiology
    • Luxms BI
    • Modus BI
    • PIX BI
    • Arenadata
    • ClickHouse
    • Greenplum
    • Postgres Professional
    • Open-source BI: Superset/Metabase
    • Loginom
    • Yandex.DataLens
    • AI / Исскуственный интеллект
    • Optimacros
    • Шины данных
  • Курсы
    • Учебный курс Информационная грамотность
    • Учебный курс для бизнес-аналитиков
    • Учебный курс для системных аналитиков
    • Учебный курс по Data Governance
    • Учебный курс Как стать CDO
    • Учебный курс Современная архитектура хранилища данных
    • Учебный курс по Fine BI
    • Учебный курс по FineReport
    • Учебный курс по DWH
    • Учебный курс по Data Science (ML, AI)
    • Учебный курс по PostgreSQL
    • Учебный курс по Apache Airflow и NiFi
    • Учебный курс по Open-source BI
    • Учебный курс по ClickHouse
    • Учебный курс по DataLens
    • Учебный курс по Loginom
    • Учебный курс по Modus BI и ETL
    • Учебный курс по Visiology
    • Учебный курс по dbt
  • Функциональные решения
    • Создание Data Lake
    • Цифровая трансформация
    • Управление по KPI
    • Финансы
    • Продажи
    • Склад
    • HR
    • Маркетинг
    • Внутренний аудит
    • Категорийный менеджмент
    • S&OP и прогнозная аналитика
    • Геоаналитика
    • Цепочки поставок (SCM)
    • AutoML
    • Process Mining
    • Сквозная аналитика
  • Компания
    • О нас
    • Руководство
    • Новости
    • Клиенты
    • Скачать
    • Контакты
    • Политика конфиденциальности
RutubeVkontakteLinkedInYouTube
ООО "Би Ай Консалт",
ИНН: 7811437757,
ОГРН: 1097847154184
199178, Россия,
Санкт-Петербург,
6-ая линия В.О., Д. 63, 4 этаж
Тел: +7 (812) 334-08-01
Тел: +7 (499) 608-13-06
E-mail: info@biconsult.ru

 

 

 

 

 

×

Пользуясь сайтом, вы соглашаетесь с использованием cookies и политикой конфиденциальности.