Тестовое задание на Angular. Работа с данными из State.
В данной статье поговорим об использовании данных из State
и рассмотрим нюансы с созданием сервисов, использующих фасады.
Данный шаг не является обязательным, и тут идет архитектурное рассуждение, которое может быть сугубо субъективным.
После того, как появился RoomState
можно попробовать вывести список комнат. Но есть один нюанс. Так как в state в начале принимает значение initialState, в котором у нас rooms равны null, то это может вызвать определенные side-effect’ы.
Поэтому чаще всего, создается сервис, который оборачивает работу RoomFacade
, следующим образом:
То есть, вместо прямого обращения к rooms$
, сначала делается проверка на наличие данных. Другими словами, Angular отреагирует на получения данных только в том случае, когда rooms будет не null
.
Но тут есть одна очень страшная ловушка, которая нечевидна.
Допустим, необходимо создать сервис, который будет объединять данные из нескольких state’ов. Например, нужно вывести все отели, и для каждого отеля вывести первый номер, который есть в данном отеле. С точки реализации мы имеем:
RoomFacade
—фасад, который предоставляет доступ к номерам;RoomService
— сервис, который фильтрует данные из state;BuildingFacade
— фасад, предоставляющий доступ к отелям;BuildingService
— сервис, который используетBuildingFacade
и фильтрует данные, предоставляя доступ к отелям.
Нужно создать сервис — BookingService
, где можно будет получить объединенные вместе отели и номера.
Вопрос в следующем, что использовать в качестве зависимостей? Пару BuildingFacade и RoomFacade или BuildomgService и RoomService?
Правильным решением является использование первой пары: BuildingFacade
и RoomFacade
. Это все связано со слоями абстракций (инфраструктурными слоями). Условно создавая новый сервис на второй паре, мы явно получаем зависимость от 2 сервисов: RoomService, который в свою очередь зависит от RoomFacade.
Другими словами можно выразить данное правило в виде — Фасад используется в “final” классе или по крайней мере, в сервисе не должно быть дублирующих свойств.
Например, в RoomFacade
есть метод clear
. Если некий сервис или компонент использует RoomService, где нужно вызвать метод clear из RoomFacade
, что нужно сделать?
Плохой вариант — создать в RoomService
метод clear
, который вызовет RoomFacade.clear()
.
И здесь плохой вариант плох тем, что помимо того, что появляется дублирование логики, так и еще появляются толстые связи. Например, в дальнейшем метод clear будет удален из Facade, что делать с данным методом в Service?
Хороший вариант — не использовать RoomService, а сразу использовать RoomFacade
и ничего не создавать. Единственное, придется продублировать логику с обращением к данным, но это часто просто один оператор filter.
Резюмируя вышесказанное:
- При работе с данными, старайтесь использовать
Facade
и не создавать дополнительных сервисов - Если же все-таки явно нужен сервис, то никогда не используйте сервис в других сервисах для получения данных из
Facade
. - Если в компоненте или сервисе потребовалось вызвать данные из
Facade
, но в данном компоненте или сервисе используется неFacade
, а обертка над ним, то необходимо отказаться от обертки и использоватьFacade
.
Ссылки
Вернуться к оглавлению — Введение.
Следующая статья — Создание lazy страницы.
Предыдущая статья — Использование Ngrx State.
Все исходники на github/fafnur/barinb.
Группа в Medium: https://medium.com/fafnur
Группа в Vkontakte: https://vk.com/fafnur
Группа в Facebook: https://www.facebook.com/groups/fafnur/
Telegram канал: https://t.me/f_a_f_n_u_r
Twitter: https://twitter.com/Fafnur1
LinkedIn: https://www.linkedin.com/in/fafnur