DDD, объекты домена /VO и JPA
Я начинаю с DDD, и вы можете представить, как мой мозг кипит.
Мой вопрос связан с моими объектами домена (сущностями, VO,...), которые представляют собой мои концепции/логику домена и как их сохранять/извлекать.
В синей книге говорится, что репозиторий - это способ представления коллекций объектов домена и отвечает за взаимодействие с уровнем инфраструктуры. Я также читаю, что на каком-то посту уровень инфраструктуры выглядит там, где вы должны использовать спящий режим, JPA или что-то еще.
Затем я вижу этот Spring -data-jpa пример http://spring.io/guides/gs/accessing-data-jpa/, и я становлюсь сумасшедшим.
Слоган говорит, что Spring -data-jpa - это легко создавать репозитории, а предыдущие образцы объединяют аннотации JPA в объект домена (customer
).
Правильно ли образец? или я прав?
Если я прав, и домен и инфраструктура должны быть разделены, это означает, что для хранения клиента у меня должно быть:
- a
customer
на моем доменном уровне (который представляет клиента и имеет все логические операции)
- a
CustomerRepository
un мой доменный уровень (который извлекает или хранит клиентов из уровня инфраструктуры)
- a
customer
в инфраструктурном слое, возможно, аннотируется с @Entity
- Некоторые
CustomerReposityJPA
, которые знают, как хранить/извлекать клиентов из базы данных.
Спасибо за любое разъяснение.
Ответы
Ответ 1
В DDD репозиторий - это объект, который участвует в домене, но действительно абстрагирует некоторые хранилища резервных копий.
Если вы аннотируете объекты домена с помощью аннотаций JPA, ваш механизм персистентности попадает в ваш домен. Вы привязали свою структуру домена к своей структуре персистентности, которая не идеальна.
Ваш JpaCustomerRepository
(реализует ICustomerRepository
) может отображать неаннотированные классы домена (Customer
) в аннотированное представление JPA - клиент JPA. Это позволяет сохранить аннотации из ваших классов домена, поэтому чище. Это позволяет вам изменять структуру сохранения JPA независимо от вашей структуры домена. Стоимость этого преимущества - сложность кода отображения.
interface ICustomerRepository {}
class JpaCustomerRepository implements ICustomerRepository {
void save(Customer customer) {
JpaCustomer jpaCustomer = map(customer);
save(jpaCustomer);
}
}
class Customer {}
class JpaCustomer {}
Ответ 2
Я не вижу ссылку, которую вы опубликовали, и я никогда не применяю проект, ориентированный на домен, в мир Java.
Теоретически, что вам нужно, - это агрегация Customer
на уровне домена. В вашем доменном слое есть место для репозитория (предназначенного как интерфейс), поэтому у вас будет ICustomerRepository
.
Вероятно, у вас будет четыре прототипа для общих проблем с сохранением:
GetById(CustomerId id);
Add(Customer c);
Delete(Customer c);
Update(Customer c);
В инфраструктурном слое вы предоставите тело (например, CustomerRepository
), в слое инфраструктуры вы можете соединить себя с чем-то технологическим (например, JPA).
Уровень домена ДОЛЖЕН быть полностью не осведомлен о технологии, используемой в инфраструктуре. При этом вы можете полностью изменить детали реализации, имеющие (почти) никаких проблем.