24 июня 2026 года InfoQ выпустил большой разбор архитектуры RDLA для offline-first Android — подхода, который предлагает перестать дергать данные из UI по запросу и вместо этого строить приложение вокруг реактивных потоков и локального хранилища. Для Android-команд это не теоретическая дискуссия про «правильные слои», а вполне практичный способ сократить бойлерплейт, пережить плохую сеть и не утонуть в гонках состояний.
Материал написал Mervyn Anthony, а по данным InfoQ, ключевая идея Reactive Data Layer Architecture сводится к жесткой границе между публичным API данных и приватной реализацией источников данных. На практике это означает, что слой представления не ходит в сеть и не опрашивает базу «по случаю», а подписывается на cold-stream-потоки Kotlin Flow и реагирует на изменения сам. Для команды, живущей в Jetpack Compose, это выглядит куда естественнее, чем старый сценарий «презентер спросил, модель ответила, экран обновился».
Главная мишень автора — классический MVP и канонический Clean Architecture в их мобильном исполнении. MVP он критикует за pull-based-поведение: если фоновый воркер обновил локальную базу, презентер сам об этом не узнает, пока его не заставят опросить состояние заново или не прикрутят еще один событийный костыль. Clean Architecture достается за другой грех: в приложениях с десятками таблиц и простыми CRUD-сценариями она легко обрастает армией «сквозных» use case-классов, которые не добавляют бизнес-логики, но исправно едят время на поддержку. RDLA пытается снять этот налог на архитектурную добродетель, не ломая сам принцип разделения зависимостей.
Архитектурно RDLA делит data-пакет на три части: API-модуль, модуль реализации и общий database-слой. В API лежат чистые Kotlin-модели и интерфейсы репозиториев без привязки к платформе, SQLite или сетевым библиотекам. Реализация прячет внутри себя все неприятное: проверку протухания кэша, фоновую синхронизацию, объединение локальных правок с данными с сервера и детали доступа к железу. Важный эффект для offline-first Android в том, что локальная база становится единственным источником правды для UI, а сеть используется только как механизм пополнения этого источника. Экрану не нужно знать, прилетели ли данные по REST, из BLE-устройства или из очереди отложенных мутаций.
Именно работа с нестабильными источниками делает статью интереснее обычного спора о паттернах. Anthony разбирает сценарии из медицинского IoT и wearable-устройств: трекеры сна, слуховые аппараты, датчики сердечного ритма. В такой среде нельзя рассчитывать на стабильную сеть и аккуратные последовательные ответы API. Bluetooth Low Energy живет на колбэках, Binder thread'ах и неприятных сюрпризах вроде GATT race condition, когда команды уходят в контроллер не по порядку или теряются вовсе. Итог знаком многим Android-разработчикам: ошибки со статусами 133 или 129, которые очень не любят объяснять себя в логах. RDLA предлагает выпрямлять этот хаос через Kotlin Coroutines и мосты на suspendCancellableCoroutine, чтобы физически асинхронные операции превращались в последовательный и детерминированный поток данных.
Отдельно автор показывает, как архитектура ведет себя в записи данных, а не только в чтении. Для пользовательских изменений предлагается использовать локальную Asynchronous Mutation Queue: действие сначала пишется в локальное хранилище, UI обновляется сразу, а фактическая синхронизация с сетью уезжает в фон. Если звучит как очередной вариант optimistic UI, то да, но здесь акцент на мобильной надежности: очередь отвязана от жизненного цикла экрана и может продолжить работу, даже если приложение уже не на переднем плане. Для этого Anthony советует использовать Android Jetpack WorkManager, чтобы критичные payload'ы не пропадали просто потому, что пользователь свернул приложение или система решила расчистить память. Для продуктовых команд это уже разговор не про красоту кода, а про снижение количества «у меня ничего не сохранилось» в поддержке.
Есть и еще один приятный побочный эффект: тестирование. RDLA поощряет разработку через интерфейсы и чистое засевание данных, а для внутренних проверок автор вводит TestExtensions interface. Такая схема позволяет гонять развязанные unit-тесты с Robolectric и проверять, например, логику fallback на локальную базу без хрупких моков SQLite. Для Android это важная деталь: многие архитектуры выглядят убедительно на схеме, но рассыпаются, когда их пытаются покрыть тестами без поднятия полприложения. Здесь же смысл как раз в том, чтобы публичный контракт данных можно было проверять отдельно от того, какой именно Room, сетевой клиент или BLE-адаптер скрыт внутри реализации.
Для рынка мобильной разработки эта публикация хорошо ложится в более широкий тренд. Android уже давно ушел от мира, где UI можно безболезненно строить вокруг разовых запросов и набора callback'ов. Jetpack Compose, Kotlin Flow, фоновые воркеры и растущие требования к работе без сети подталкивают команды к архитектурам, где реактивность и локальный кэш не «опция на потом», а базовое условие. RDLA в этом смысле не пытается свергнуть MVVM или переписать Clean Architecture заново: автор прямо позиционирует подход как мобильную специализацию data layer и части domain layer. Вопрос теперь в другом: сколько Android-команд готовы честно признать, что лишние use case-классы, ручная синхронизация состояний и опрос базы по событию — это не инженерная дисциплина, а просто дорогая привычка.