В типичном Android-проекте, где нам нужно как-то извлекать данные из (REST, SQL, cache и т.д.) В пользовательский интерфейс, мы обычно используем Loader, Service или (возможно, yuk) AsyncTask, но я нахожу все эти подходы неудовлетворительно по нескольким причинам:
- Они уродливые, особенно Loaders, у которых ужасная структура API
- Это слишком просто, чтобы обернуться в потоки и наступить на поток пользовательского интерфейса
- Наш код уровня презентации загрязняется кодом Android и шаблоном. Мы часто передаем объекты Android (например, курсоры) прямо на уровень пользовательского интерфейса, что делает невозможным достижение чистой архитектуры. Это заставляет нас смешивать специфический код бизнес-домена (в идеале простые объекты Java) с кодом платформы Android - не очень подходит для читаемости, обслуживания, тестирования или гибкости для будущей разработки. На практике мы часто получаем огромные, грязные классы Activity/Fragment.
Меня привлекают такие идеи, как те, которые описаны в этих статьях: http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/ http://antonioleiva.com/mvp-android/ http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
Успешно приступив к использованию MVP, чтобы разбить "Действия/Фрагменты/Представления" на части меньшего размера/чистого, я теперь думаю, что решение вышеперечисленных проблем может заключаться в том, чтобы полагаться на шину сообщений (Otto, EventBus и т.д.) Вместо служб или загрузчики или что-либо другое для взаимодействия с данными домена.
Поэтому на практике это означало бы вместо использования (например) CursorLoader для загрузки курсора из базы данных, вместо этого я бы использовал шину сообщений для отправки сообщения для запроса данных, данные загружаются в фоновый поток в ответ на это сообщение, а затем обрабатывать данные ответа, когда он поступает через сообщение в потоке пользовательского интерфейса. Для меня очень важно, чтобы структура данных была исключена из бизнес-домена, а не из домена Android, поэтому я предпочел бы массив бизнес-объектов для курсора.
При разработке всегда есть компромиссы, и хотя это, по-видимому, обеспечивает гораздо более четкое разделение проблем, там меньше загрузочного/сервисного шаблона, каковы недостатки?
- Может быть сложнее (особенно для новых разработчиков) понять код
- Необходимо будет обеспечить отправку и получение сообщений по нужным потокам (похоже, у Отто есть ограничения)
- Необходимо будет избежать соблазна реализовать все как сообщение, которое в конечном итоге будет контрпродуктивным
- Передача коллекций бизнес-объектов вокруг может быть менее эффективной, чем использование объектов, таких как курсоры. Хотя во многих сценариях это проблема на практике?
- Я не знаю, предназначены ли Otto/EventBus только для передачи очень маленьких сообщений или целесообразно передавать более крупные объекты (например, массив бизнес-объектов).
Мой вопрос в том, есть ли какие-либо основополагающие причины, чтобы не использовать этот подход, основанный на сообщениях, с приложениями для Android?