Мы внимательно изучаем наши шаблоны веб-приложений (Java). Раньше мы страдали от чрезмерно анемичной объектной модели и чрезмерно процедурного разделения между контроллерами, службами и DAO, с простыми объектами ценности (в основном просто мешками данных), перемещающимися между ними. Мы использовали декларативный (XML) управляемый ORM (Hibernate) для сохранения. Управление всеми сущностями происходило в DAO.
При попытке перейти к более богатой модели домена мы сталкиваемся с тем, как лучше всего разрабатывать слой persistence. Я потратил много времени на чтение и размышление о шаблонах проектирования Driven Design. Тем не менее, я хотел бы получить совет.
Во-первых, вещи, о которых я более уверенно:
-
У нас будут "тонкие" контроллеры спереди, которые имеют дело только с форматами обработки HTTP и HTML, валидацией, логикой пользовательского интерфейса.
-
У нас будет уровень служб бизнес-логики без состояния, который реализует общие алгоритмы или логику, не подозревая о пользовательском интерфейсе, но очень хорошо понимает (и делегирует) модель домена.
-
У нас будет более богатая модель домена, которая содержит состояние, отношения и логику, присущие объектам в этой модели домена.
Вопрос о настойчивости. Раньше наши сервисы были бы введены (через Spring) с помощью DAO и будут использовать методы DAO, такие как find() и save() для выполнения сохранения. Однако более богатая модель домена, по-видимому, подразумевает, что объекты должны знать, как сохранять и удалять себя, и, возможно, что услуги более высокого уровня должны знать, как найти (запрос для) объектов домена.
Здесь возникает несколько вопросов и неопределенностей:
-
Мы хотим внедрить DAO в объекты домена, чтобы они могли выполнять "this.someDao.save(this)" в методе save()? Это немного неудобно, так как объекты домена не являются одноточиями, поэтому нам понадобятся фабрики или пост-строительная установка DAO. При загрузке объектов из базы данных это становится беспорядочным. Я знаю, что для этого можно использовать Spring AOP, но я не мог заставить его работать (используя Play! Framework, еще одну линию экспериментов), и это кажется довольно грязным и волшебным.
-
Не будем ли мы полностью разделять DAO (репозитории?) наравне с службами бизнес-логики без состояния? Это может иметь определенный смысл, но это означает, что если "сохранить" или "удалить" являются неотъемлемыми операциями объекта домена, объект домена не может выразить их.
-
Мы просто обойдемся с DAO полностью и используем JPA, чтобы позволить сущности управлять собой.
В этом заключается следующая тонкость: довольно удобно отображать объекты, используя JPA. Игра! framework дает нам хороший класс базовых объектов тоже с такими операциями, как save() и delete(). Однако это означает, что наши объекты модели домена довольно тесно связаны с структурой базы данных, и мы передаем объекты с большой логикой постоянства, возможно, вплоть до уровня представления. Если ничего другого, это сделает модель домена менее пригодной для повторного использования в других контекстах.
Если мы хотим избежать этого, нам потребуется какое-то отображение DAO - либо с использованием простого JDBC (или, по крайней мере, Spring JdbcTemplate), либо с использованием параллельной иерархии объектов базы данных и "бизнес-сущностей", DAO навсегда копируют информацию из одной иерархии в другую.
Каков правильный выбор дизайна здесь?
Martin