#android #архитектура
Исходные классы: EventListPresenter и EventFiltersPresenter - презентеры, EventRepository - репозиторий, EventFilters - java класс, который содержит поля фильтров. Задача: EventListPresenter должен уметь отображать Event по фильтрам. Пользователь настраивает фильтры на отдельном экране. После настройки фильтров нажимает кнопку "Применить" и переходит обратно на экран со списком, но уже должны примениться новые фильтры. Как это правильно сделать в Чистой архитектуре? Слышал, что делать это через ActivityOnResult - плохая практика, можете объяснить почему и как правильно, если можно с примером (псевдокод)?
Ответы
Ответ 1
Чистая архитектура говорит только о зависимостях между слоями приложения (бизнес логика ничего не знает о внешнем представлении и так далее). Понятие "экранов" в приложении относится к презентейшн слою, который можно реализовать различными MV* паттернами. Например MVP. Самое удобное и правильное для передачи событий между экранами (то есть между их презентерами) - создать общую модельку CurrentFilter с текущим фильтром в памяти. Тогда EventListPresenter подпишется на обновления этой модельки и будет реагировать на изменения фильтра, то есть запрашивать новые данные из репозитория. А EventFiltersPresenter будет менять фильтр внутри этой модельки. Есть множество способов это реализовать, но наиболее распространенным является использование CustomScoup Dagger 2. То есть первый презентер EventListPresenter при инициализации создаст CurrentFilter, а при уничтожении очистит. Так как второй экран запускается заведомо после EventListPresenter, то для него CurrentFilter уже будет доступен. Использование onActivityResult допустимо для запуска внешних приложений типа камеры, тогда результат полученный в Intent передается презентеру и дальше уже обрабатывается там. В других случаях это менее удобно, так как передавать можно только серелизуемые данные и в ответственность Активити попадает еще и логика передачи данных кроме отображения.Ответ 2
Если вы хотите следовать принципам "чистой архитектуры", под которой имеется ввиду строгое распределение на слои, каждый из которых отвечает только за свой конкретный отрезок работы (Single Responsibility), то использоваеonActivityResult нарушает как раз нарушает принцип единой ответственности слоя. Рассмотрим распостраненный вариант архитектуры: View -> Presenter -> Repository -> Model Каждый знает только о следующем и/или предыдущем слое. То есть Model ничего не знает о Presenter и View. На всякий случай уточню, что View это зачастую Activity или Fragment. И тут непресредственно ответ на Ваш последний вопрос: onActivityResult вернет Вашу модель во View (который ответственный за вызов новых экранов), то есть в слой, который как бы за модель не ответственный. Если придерживаться такой архитектуре, то используется interactor. Обычно он представляет собой интерфейс, с одним методом interaction(), который выполняет задачу и передает данные/модели средствами Event bus, который "слушает" нужные события в нужных местах. Своим ответом я не заявляю о правильности использования только такого подхода. Такие вопросы всегда являются повод демагогий и бесконечных обсуждений, но в итоге все соглашаются, что к правильной (значит гибкой, расширяемой и взаимозаменяемой) архитектуре надо стремиться, но единственного правильного варианта нет, а каждый выбирает что ему удобнее. Рекомендую ознакомиться с архитектурным гайдом от гугла, который был представлен на Google I/O 2017.
Комментариев нет:
Отправить комментарий