Многоуровневая архитектура в проекте на Java (Часть 2)

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

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

Валидацию и проверку прав доступа в нашем проекте будут реализовывать NoteValidationService (или NoteValidator, как вам удобнее и привычнее) и NoteAccessValidationService, соответственно.

Выделение этой функциональности в отдельные компоненты соответствует принципу единой ответственности (SRP) — если изменяются правила валидации, то изменения будут вноситься только в NoteValidationService, а если изменяются правила проверки доступа, то изменения коснутся только NoteAccessValidationService. А объявление этих компонентов в виде интерфейсов соотвествует принципу инверсии зависимостей (DIP), так как оба сервиса вполне могут использовать сторонние зависимости: так реализация NoteAccessValidationService может использовать для определения прав доступа Spring Security, а NoteValidationService — Bean Validation API (оба варианта будут продемонстрированы в моих следующих статьях на эту тему).

Создадим недостающие интерфейсы и класс AdvancedNoteService, который будет реализовывать бизнес-логику работы с заметками с использованием новых компонентов. UML-диаграмма классов на этот раз будет выглядеть примерно так:

Необходимость в проверке прав доступа (и авторизации в целом) привела к тому, что у всех методов NoteService добавился аргумент, в котором должен передаваться идентификатор пользователя, а в NoteRepository добавился метод findAll, запрашивающий все заметки пользователя.

Теперь опишем тесты AdvancedNoteService:

и напишем реализацию класса, которая будет удовлетворять условиям тестов:

Бизнес-логика нашего проекта теперь реализует не только CRUD, но и валидацию и проверку прав доступа. Однако компоненты, ответственные за валидацию и проверку прав доступа, не реализованы, как и единственный компонент слоя доступа к данным — NoteRepository. Об этом пойдёт речь в следующих статьях.