Поддержание чистой архитектуры в Spring MVC с ориентированным на данные подходом
Я пытаюсь отобразить архитектуру для внешнего интерфейса нового веб-приложения на основе Java (приложение типа портала), которое мы делаем на работе. Я хочу получить это право с первого дня, и я хотел бы начать обсуждение здесь, чтобы помочь мне реализовать дядю Боба "Чистая архитектура" в моей архитектурной дизайн.
Здесь быстрый прорыв нашего технического стека, сверху вниз (технология не важна, структура):
- База данных Oracle
- Oracle Service Bus, предоставляющая услуги с использованием WSDL
- JAX-WS генерирует Java-классы из WSDL (позвольте назвать этот "сгенерированный сервисный уровень" )
- Модуль домена, состоящий из POJO, сопоставленных с созданными объектами данных
- Потребительский модуль, отображающий "сгенерированный сервисный уровень" для внешнего приложения.
- A Spring Основанный на MVC модуль с использованием FreeMarker для визуализации представлений
Ключевой момент:
В частности, имя того, что объявлено во внешнем круге, не должно упоминаться кодом внутри внутреннего круга. Это включает в себя функции, классы. переменные или любой другой названный программный объект.
Попытка присоединиться к архитектуре Bob Clean Architecture, я немного поучался себе в том, где разместить логику приложения, а именно слой "Use Case" в его архитектуре.
Вот такой подход, который я придумал:
Уровень 1 - Объекты
Объекты заключают в себе корпоративные бизнес-правила.
Здесь находится наш доменный модуль, содержащий объекты домена, это самосодержимые объекты с минимальными зависимостями друг от друга. Только логика, относящаяся к самим объектам, может жить на этих объектах домена и не использовать конкретную логику использования.
Доступ к нашей базе данных осуществляется через WSDL с использованием служебной шины, которая преобразует данные, в отличие от ORM, например JPA или Hibernate. Из-за этого у нас нет "сущностей" в традиционном смысле (с идентификаторами), но подход, ориентированный на данные, делает этот слой уровнем доступа к данным, представленным остальной частью приложения модулем Consumer.
Уровень 2 - Использовать случаи
Программное обеспечение на этом уровне содержит бизнес-правила, специфичные для приложения.
Здесь логика, специфичная для нашего приложения, использует случаи жизни. Изменения этого слоя не должны влиять на уровень доступа к данным (уровень 1). Изменения в реализации GUI или каркаса (Spring MVC) не должны влиять на этот уровень.
Здесь он становится немного сложным:
Поскольку наш уровень доступа к данным (в слое 1) должен быть очищен от логики приложения, нам нужен слой, который облегчает использование этого слоя таким образом, который подходит для использования. Одним из решений, которое я нашел для этой проблемы, является использование варианта "MVVM-шаблона", который я выбираю для вызова MVC-VM. См. Ниже объяснение. "VM" -части этого живет в этом "Использовании Case-слоя", представленном *ViewModel
-классами, которые инкапсулируют эту логику с использованием конкретного случая.
Уровень 3 - Адаптеры интерфейса
Программное обеспечение на этом уровне представляет собой набор адаптеров, которые преобразуют данные из формата, наиболее удобного для использования и сущностей, в формат, наиболее удобный для некоторых внешних агентств, таких как База данных или Интернет.
Здесь находится MVC-архитектура нашего GUI ( "MVC" в нашей "MVC-VM" ). По существу это когда классы Controller
получают данные из классов *ViewModel
и помещают его в теги Spring MVC ModelMap
, которые напрямую используются шаблонами FreeMarker в представлении.
То, как я это вижу, servicebus в нашем случае также попадет под этот слой.
Уровень 4 - Рамки и драйверы
Как правило, вы не пишете много кода в этом слое, кроме кода клея, который связывается со следующим кругом внутрь.
Этот уровень - это всего лишь слой конфигурации в нашем приложении, а именно конфигурация Spring. Это будет, например, указать, где мы указываем, что FreeMarker используется для визуализации представления.
Модель ViewModel Pattern
MVVM облегчает четкое разделение разработки графического пользовательского интерфейса (либо как язык разметки, либо код GUI) от разработки бизнес-логики или логики конца, известной как модель (также известная как модель данных, чтобы отличить ее из модели просмотра). Модель представления MVVM представляет собой преобразователь значений, означающий, что модель представления отвечает за отображение объектов данных из модели таким образом, что эти объекты легко управляются и потребляются.
Подробнее о MVVM-шаблоне в Wikipedia.
Роли MVC-VM выполняются в нашем приложении так:
- Модель - представлена просто datastructure
ModelMap
в Spring MVC, которая используется шаблонами представлений. - Просмотр - шаблоны FreeMarker
-
Контроллер Spring
Controller
-классы, которые направляют запросы URL-адресов HTTP определенным обработчикам (и как такие функции, как FrontController). Обработчики в этих классах отвечают за выборку данных из прецедента и вывод его в шаблоны представлений при показе данных (HTTPGET
), а также передачу данных для хранения (HTTPPOST
). Таким образом, он по существу функционирует как связующее средство между ViewModel и View, используя Model. -
ViewModel. Эти классы отвечают за: 1) структурирование данных с уровня доступа к данным способом, который можно использовать View и 2) обрабатывать данные ввода из представления. "Обработка" означает проверку и разбиение данных, чтобы их можно было отправить в стек для хранения. Этот слой будет выглядеть как
<UseCase>VM
-классы в пакетеviewmodel
в нашем интерфейсе Spring MVC.
Ключевым компонентом здесь является неявное связывание, которое происходит в Spring MVC между ModelMap
и шаблонами FreeMarker. Шаблоны используют только модель (ModelMap
s), где контроллер помещает данные в формат, который он может использовать. Таким образом мы можем сделать шаблоны так:
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
Я извиняюсь за подробное объяснение, но я не мог объяснить эту (относительно простую) архитектуру в меньшем количестве слов.
Я был бы очень признателен за внесенный вклад в мой подход здесь - я на правильном пути? Имеет ли смысл MVC-VM смысл? Я нарушаю принципы чистой архитектуры?
Конечно, есть много решений для этого, но я пытаюсь найти решение, которое является 1) не чрезмерно спроектированным и 2) придерживается принципов архитектуры Bob Clean.
Обновление:
Я думаю, что ключевая проблема, которая меня отталкивает, заключается в том, какую форму использует слой "Use case" в этом приложении. Помните, что у нас есть интерфейс MVC, который получает данные с уровня доступа к данным. Если часть MVC соответствует Бобу "Интерфейсные адаптеры", а модели домена слоя данных соответствуют слою "Entities" Боба, то что я называю классами использования, которые реализуют логику приложения? У меня возникает соблазн просто называть их <UseCase>Model
и помещать их в проект MVC, но согласно Bob
Модели, скорее всего, представляют собой только структуры данных, которые передаются от контроллеров к прецедентам, а затем обратно из вариантов использования в представления и представления.
так что мои объекты модели должны быть "тупыми" (как простой Map
. ModelMap
в Spring), а затем контроллер должен помещать данные из класса Use Case в эту карту -состав.
Итак, в какой форме используются мои классы использования Case? Как насчет <UseCase>Interactor
?
Но в заключение я понимаю, что MVC-MV-вещь является чрезмерной (или просто неверной) - поскольку "mikalai" указывает ниже, это, по существу, просто двухслойное приложение в его текущей форме; уровень доступа к данным и внешний уровень MVC. Просто как это.