Зачастую в нашем домене имеются модели, требующие быть уникально идентифицированными в рамках нашего приложения.
Например такими моделями могут являться:
- автомобиль в системе учета транспорта
- пользователь в приложении
- заказ в интернет магазине
Все они должны иметь уникальный идентификатор, чтобы мы могли отличать их от аналогичных.
2 способа идентификации моделей.
- Уникальное поле в модели — как скалярный тип: числовой или строковый.
- Уникально поле в модели представлено объектом VO.
Какие преимущества делать уникально поле как VO?
- Объекты значения VO иммутабельны, а значит после создания никто не сможет «случайно» изменить его значение.
- VO могут иметь поведение, через методы объектов VO можно удобно выяснить эквивалентность одного VO другому VO и принять решение что Entity эквивалентна. Такие методы удобно инкапсулированы внутри VO и не требует создания дополнительных классов сервисов.
Идентификатор обычно создается/представляется одним из следующих вариантов:
- слой хранения предоставляет уникальный идентификатор
- клиент предоставляет уникальный идентификатор
- само приложение генерирует уникальный идентификатор
- другой домен предоставляет уникальный идентификатор
Кейс когда идентификатор генерирует слой хранения данных.
Это один из самых частых и удобных случаев, когда данные нашей Entity хранятся например, в реляционной базе данных (как например MySql или Postgres) то первичный ключ ввиде автоинкремента уникально идентифицирует запись в таблице и также используется в Entity как уникальный идентификатор сущности.
Как недостаток в некоторых системах такой подход становится узким неудобным горлышком по причине того что Entity получит идентификатор только после сохранения в persistence слое.
Также встает вопрос выбора паттерны для работа с БД: Active Record VS Data Mapper.
Зачастую наши модели собираются из нескольких источников данных и здесь Active Record неудобен, потому что строго привязывает структуру нашей модели к схеме таблицы в БД. Doctrine с подходом Data Mapper — такий ограничений не создает.
Кейс когда идентификатор от внешней системы.
Бывают случаи, что нам вообще не надо задумывать об идентификаторе — он к нам приходит извне естественным путем.
Такими примерами может являться:
- ISBN который имеют все книги
- номер блока в blockchain биткойна.
- и т.д.
Кейс когда идентификатор генерирует само приложение.
Это один из удобнейших подходов, особенно если мы имеем дело с распределенными системами, микросервисной архитектурой и т.д.
Самый частый способ это генерировать UUID — удобно, быстро и большая гарантия неповторимости.
Рекомендуемым местом для генерации UUID — является например Репозиторий.
Summary
Entity это модели нашей доменной области, которые могут быть уникально идентифицированы своим уникальным id. Рекомендуемый способ реализации id в entity — это VO, которые гарантирует иммутабельность значения.