SlideShare a Scribd company logo
1 of 32
Download to read offline
СТРАХ И НЕНАВИСТЬ В
EVENT-BUS
Олег Годовых
AT FIRST IT WAS LIKETHIS
BUTTHEN I UMLD…
МАГАЗИНЧИК
• 500 страниц документации.
• В том числе 200 страниц
описания API.
• Большое количество сложных
use-cases.
• Разветвлённая логика и схема
зависимостей.
МАГАЗИНЧИК
• 4 человеко-года на каждую платформу (iOS,Android).
• 6 разработчиков в команде Android.
• Общий размер команды — до 27 человек.
• ≈40000 строк кода.
ОСОБЕННОСТИ
• Android 4.0+
• Одно действие — один запрос.
• Настройками кэширования занимается сервер.
• Ссылки для последующих запросов приходят с сервера.
ПРОБЛЕМЫ
• Много разнородных запросов (около 100 в последней
версии API).
• Компонент-инициатор != компонент-получатель.
• Инициаторов может быть несколько.
• Получателей тоже!
КАК ДЕЛАТЬ ЗАПРОСЫ
• In-place AsyncTask.
• AQuery и иже с ними.
• Сервисы, контент-провайдеры, броадкасты…
• Реактивное программирование.
ЧЕМ ПЛОХИ ASYNCTASK
• Очень сложно переиспользовать.
• Очень много boilerplate-кода.
• Гроб, гроб, кладбище, утечка контекста.
requestDataTask = new AsyncTask<Void, Void, JSONObject>() {
@Override
protected JSONObject doInBackground(Void... params) {
final String requestResult = apiService.getData();
final JSONObject json = JsonUtils.parse(requestResult);
lruCache.cacheJson(json);
return json;
}
};
AsyncTask
Понятность +
Удобство -1
Переисполь
зование
—
Пацаны так
делают?
—
ПОЧЕМУ НЕ КАТИТ AQUERY
• Слишком локальное применение.
• Опять же — много повторяющегося кода.
• Сложно прикручивать другие библиотеки.
aq.ajax("http://example.com", String.class, CACHE_TIME, new AjaxCallback<String>() {
@Override
public void callback(String url, String object, AjaxStatus status) {
Type listType = new TypeToken<List<User>>() {}.getType();
List<User> list = new Gson().fromJson(object, listType);
listener.onResponse(list);
}
});
AsyncTask AQuery
Понятность + +
Удобство -1 2
Переисполь
зование
— —
Пацаны так
делают?
— ≈
ДАВАЙТЕ ПОСЛУШАЕМ
GOOGLE IO
• Храним в БД
• Скачиваем сервисом
• Отдаём через ContentProvider
ЧТО НЕ ТАК С CP
• Дважды конструируем
объект (при разборе
результата запроса и
при десериализации из
БД).
• Нужно инвалидировать
данные. Зачем нам SQL?
Нам SQL не нужен
AsyncTask AQuery Service + CP
Понятность + + ≈
Удобство -1 3 2
Переиспользо
вание
— — +
Не делаем
лишнего
— + —
Пацаны так
делают?
— ≈ +
ГОТОВЫЙ ФРЕЙМВОРК
• Сильная связность
• Есть явная «точка сопряжения»
final Subscription subscription =
createApiRequestObservable() //создали Observable с запросом
.timeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS) //поставили таймаут
.retry(RETRY_COUNT_FOR_REQUEST) //поставили кол-во повторов
.onErrorResumeNext(createRequestErrorHandler()) // назначили обработчик ошибки
.map(createJsonMapOperator()) //модифицировали Observable, чтобы получать JSONObject
.onErrorReturn(createJsonErrorHandler()) //возвращаем в случае ошибки то, что ожидаем
.doOnNext(createCacheOperation()); //кэшируем JSONObject
.subscribeOn(Schedulers.newThread()) //трудоёмкое в отдельном потоке
.observeOn(AndroidSchedulers.mainThread()) // обработка результата - в main thread
.subscribe(subscriber); //обработчик результата
AsyncTask AQuery
Service +
CP
RxJava
Понятность + + ≈ ≈
Удобство -1 3 2 4
Переиспользо
вание
— — + +
Не делаем
лишнего
— + — ≈
Пацаны так
делают?
— ≈ + +
VOLLEY
• Несколько уровней кэширования.
• Абстрагируемся от HTTP насколько возможно.
• Очень гибкое управление очередью.
ТИПИЧНАЯ СХЕМА
ДЕЙСТВИЙ
• Создаём по действию новый запрос
• Добавляем его в очередь
• Забываем
• …
• ОТВЕТ СЕРВЕРА!!!
ОТВЕТ СЕРВЕРА
• Распространяется через event bus.
• Все желающие его получают.
• Не страшно, если никому он уже не нужен.
НИ КАПЕЛЬКИ НЕ СТРАШНО
OTTO
• Подписка на события через
аннотации.
• Подписались на то, что не
приходит — не страшно.
• Приходит то, на что не
подписывались — не беда!
public class BaseFragment extends Fragment {
protected Bus bus = AzbukaApplication.getBus();
@Override
public void onResume() {
super.onResume();
bus.register(this);
NetworkFacade.cancelOldRequests(this);
}
@Override
public void onPause() {
super.onPause();
bus.unregister(this);
NetworkFacade.markToCancel(this);
}
ЧЕМ МАНИПУЛИРУЕМ
• BaseRequest — инкапсулирует парсинг и рассылку
сообщений
• BaseResponse — bean + id
public static class PutUserNickRequest extends BaseRequest<PutUserNickResponse, NewUserNick,
PutUserNickError> {
/**
* API v0.36 p. 74, Change user password (4.10.4)
* @param url - POST /user/<user-id>/phone
* @param nick - typed nick
*/
public PutUserNickRequest(String url, String nick) {
super(Method.PUT, url, PutUserNickResponse.class, PutUserNickError.class, new
NewUserNick(nick));
}
}
ПОДПИСКА
• Нам не важно, кто отправил.
• Нам нужно лишь уметь обрабатывать данный тип ответа.
• Кто на экране — тот и главный!
@Subscribe
public void onResponse(BasketRequest.BasketContentResponse basketContentResponse) {
loadWelcome();
}
@Subscribe
public void onError(OtherError error) {
if (TextUtils.isEmpty(error.getMessage())) {
Toast.makeText(getActivity(), getString(R.string.failed), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show();
}
}
LET IT CRASH
• Есть одна точка получения данных об ошибке.
• Есть один общий workflow обработки ошибки.
• При особой надобности — можем подписаться на
ошибки конкретного класса.
ПОДВОДНЫЕ КАМНИ
• Event bus хорош, когда всё в нём хорошо.
• Отладка — снежный ком.
ПЛЮСЫ И ПЛЮШКИ
• Лёгкая проверка работоспособности back-end.
• Часть приложения сделана как конечный автомат на
основе Event Bus.
• Архитектура «непривязанных запросов» отлично ложится
почти на любое приложение.
СПАСИБО ЗА ВНИМАНИЕ
А ещё я в твиттере есть,
меня @0leGG зовут,
там 0 как нолик,
а не как Олежка.

More Related Content

What's hot

Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)
Ontico
 
Ec2 Rootconf2009
Ec2 Rootconf2009Ec2 Rootconf2009
Ec2 Rootconf2009
Liudmila Li
 
Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)
Andrey Smirnov
 
Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)
Andrey Smirnov
 
Арсений Заречнев и Федор Шумов - Одностраничные приложения
Арсений Заречнев и Федор Шумов - Одностраничные приложенияАрсений Заречнев и Федор Шумов - Одностраничные приложения
Арсений Заречнев и Федор Шумов - Одностраничные приложения
Arseny Zarechnev
 
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Ontico
 

What's hot (20)

Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)Евгений Потапов (Сумма Айти)
Евгений Потапов (Сумма Айти)
 
Ec2 Rootconf2009
Ec2 Rootconf2009Ec2 Rootconf2009
Ec2 Rootconf2009
 
08 - Web-технологии. Архитектура frontend-backend
08 - Web-технологии. Архитектура frontend-backend08 - Web-технологии. Архитектура frontend-backend
08 - Web-технологии. Архитектура frontend-backend
 
15 - Web-технологии. Сессии и авторизация
15 - Web-технологии. Сессии и авторизация15 - Web-технологии. Сессии и авторизация
15 - Web-технологии. Сессии и авторизация
 
Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)Анатомия веб сервиса (HighLoad-2014)
Анатомия веб сервиса (HighLoad-2014)
 
PowerShell
PowerShellPowerShell
PowerShell
 
Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)Анатомия веб-сервиса (РИТ-2014)
Анатомия веб-сервиса (РИТ-2014)
 
07 - Web-технологии. Web-сервера
07 - Web-технологии. Web-сервера07 - Web-технологии. Web-сервера
07 - Web-технологии. Web-сервера
 
Зачем программистам Ansible
Зачем программистам AnsibleЗачем программистам Ansible
Зачем программистам Ansible
 
Петренко Дмитрий - Серверное обеспечение для PBN без футпринтов для Google
Петренко Дмитрий - Серверное обеспечение для PBN без футпринтов для GoogleПетренко Дмитрий - Серверное обеспечение для PBN без футпринтов для Google
Петренко Дмитрий - Серверное обеспечение для PBN без футпринтов для Google
 
Андрей Федоренчик- «Высоконагруженная система с аналитикой на InfoBright»
Андрей Федоренчик- «Высоконагруженная система с аналитикой на InfoBright»Андрей Федоренчик- «Высоконагруженная система с аналитикой на InfoBright»
Андрей Федоренчик- «Высоконагруженная система с аналитикой на InfoBright»
 
Арсений Заречнев и Федор Шумов - Одностраничные приложения
Арсений Заречнев и Федор Шумов - Одностраничные приложенияАрсений Заречнев и Федор Шумов - Одностраничные приложения
Арсений Заречнев и Федор Шумов - Одностраничные приложения
 
02 - Web-технологии. Web-клиенты
02 - Web-технологии. Web-клиенты02 - Web-технологии. Web-клиенты
02 - Web-технологии. Web-клиенты
 
Суперсилы Chrome developer tools
Суперсилы Chrome developer toolsСуперсилы Chrome developer tools
Суперсилы Chrome developer tools
 
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
 
09 - Web-технологии. MVC фреймворки
09 - Web-технологии. MVC фреймворки09 - Web-технологии. MVC фреймворки
09 - Web-технологии. MVC фреймворки
 
Основные аспекты управления веб-проектом в Microsoft Azure Websites
Основные аспекты управления веб-проектом в Microsoft Azure WebsitesОсновные аспекты управления веб-проектом в Microsoft Azure Websites
Основные аспекты управления веб-проектом в Microsoft Azure Websites
 
04 web server_deployment_ru
04 web server_deployment_ru04 web server_deployment_ru
04 web server_deployment_ru
 
Настройки индексации сайта
Настройки индексации сайтаНастройки индексации сайта
Настройки индексации сайта
 
Ice Php Framework Preview Release
Ice Php Framework Preview ReleaseIce Php Framework Preview Release
Ice Php Framework Preview Release
 

Similar to Олег Годовых «Страх и ненависть в Event Bus»

2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере
Yandex
 
Система обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на GroovyСистема обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на Groovy
Regn
 
YuryByyanov (e-legion) @ CodeCamp2011
YuryByyanov (e-legion) @ CodeCamp2011YuryByyanov (e-legion) @ CodeCamp2011
YuryByyanov (e-legion) @ CodeCamp2011
CodeCamp
 
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDBCodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest
 
Серверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDBСерверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDB
Stepan Stolyarov
 
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?
buranLcme
 

Similar to Олег Годовых «Страх и ненависть в Event Bus» (20)

Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
 
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
 
2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере
 
Практические примеры использования API в инфраструктурных продуктах Cisco для...
Практические примеры использования API в инфраструктурных продуктах Cisco для...Практические примеры использования API в инфраструктурных продуктах Cisco для...
Практические примеры использования API в инфраструктурных продуктах Cisco для...
 
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.js введение в технологию, КПИ  #ITmeetingKPINode.js введение в технологию, КПИ  #ITmeetingKPI
Node.js введение в технологию, КПИ #ITmeetingKPI
 
Антон Шлома. Drupal очереди.
Антон Шлома. Drupal очереди. Антон Шлома. Drupal очереди.
Антон Шлома. Drupal очереди.
 
Система обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на GroovyСистема обработки бизнес-логики server-side приложения на Groovy
Система обработки бизнес-логики server-side приложения на Groovy
 
Юрий Буянов «Архитектура Goozy»
Юрий Буянов «Архитектура Goozy»Юрий Буянов «Архитектура Goozy»
Юрий Буянов «Архитектура Goozy»
 
YuryByyanov (e-legion) @ CodeCamp2011
YuryByyanov (e-legion) @ CodeCamp2011YuryByyanov (e-legion) @ CodeCamp2011
YuryByyanov (e-legion) @ CodeCamp2011
 
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
 
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDBCodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
CodeFest 2010. Столяров С. — Серверный JavaScript: NodeJS и CouchDB
 
Серверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDBСерверный JavaScript: NodeJS и CouchDB
Серверный JavaScript: NodeJS и CouchDB
 
Phalcon - самый быстрый PHP Framework
Phalcon - самый быстрый PHP FrameworkPhalcon - самый быстрый PHP Framework
Phalcon - самый быстрый PHP Framework
 
Meet Magento Belarus - Alexander Kaigorodov
Meet Magento Belarus - Alexander KaigorodovMeet Magento Belarus - Alexander Kaigorodov
Meet Magento Belarus - Alexander Kaigorodov
 
Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?Построение собственного JS SDK — зачем и как?
Построение собственного JS SDK — зачем и как?
 
RESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentationRESTful API: Best practices, versioning, design documentation
RESTful API: Best practices, versioning, design documentation
 
Денис Иванов
Денис ИвановДенис Иванов
Денис Иванов
 
Чуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОПЧуть сложнее чем Singleton: аннотации, IOC, АОП
Чуть сложнее чем Singleton: аннотации, IOC, АОП
 
Zabbix в сервисной компании  ОНЛАНТА - Zabbix Meetup Moscow
Zabbix в сервисной компании  ОНЛАНТА -  Zabbix Meetup Moscow Zabbix в сервисной компании  ОНЛАНТА -  Zabbix Meetup Moscow
Zabbix в сервисной компании  ОНЛАНТА - Zabbix Meetup Moscow
 
Web and mobile development for intersystems caché, Eduard Lebedyuk
Web and mobile development for intersystems caché, Eduard LebedyukWeb and mobile development for intersystems caché, Eduard Lebedyuk
Web and mobile development for intersystems caché, Eduard Lebedyuk
 

More from DevDay

Devops-практики в разработке решений для бизнеса, Максим Пашук
Devops-практики в разработке решений для бизнеса, Максим ПашукDevops-практики в разработке решений для бизнеса, Максим Пашук
Devops-практики в разработке решений для бизнеса, Максим Пашук
DevDay
 
«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин
«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин
«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин
DevDay
 

More from DevDay (20)

«Bdd и реактивщина в 2ГИС», Евгений Тютюев
«Bdd и реактивщина в 2ГИС», Евгений Тютюев«Bdd и реактивщина в 2ГИС», Евгений Тютюев
«Bdd и реактивщина в 2ГИС», Евгений Тютюев
 
«Интеграция push-уведомлений в Яндекс.Браузер под iOS», Юрий Музюкин
«Интеграция push-уведомлений в Яндекс.Браузер под iOS», Юрий Музюкин«Интеграция push-уведомлений в Яндекс.Браузер под iOS», Юрий Музюкин
«Интеграция push-уведомлений в Яндекс.Браузер под iOS», Юрий Музюкин
 
«Я спросил у сервера...», Илья Пастушков
«Я спросил у сервера...», Илья Пастушков«Я спросил у сервера...», Илья Пастушков
«Я спросил у сервера...», Илья Пастушков
 
Фреймворк Slot, Good Parts, Александр Бирюков
Фреймворк Slot, Good Parts, Александр БирюковФреймворк Slot, Good Parts, Александр Бирюков
Фреймворк Slot, Good Parts, Александр Бирюков
 
Рендеринг может больше: vue.js vs React, Андрей Солодовников
Рендеринг может больше: vue.js vs React, Андрей СолодовниковРендеринг может больше: vue.js vs React, Андрей Солодовников
Рендеринг может больше: vue.js vs React, Андрей Солодовников
 
Devops-практики в разработке решений для бизнеса, Максим Пашук
Devops-практики в разработке решений для бизнеса, Максим ПашукDevops-практики в разработке решений для бизнеса, Максим Пашук
Devops-практики в разработке решений для бизнеса, Максим Пашук
 
Inversion of Control в деталях, Дмитрий Кожевников
Inversion of Control в деталях, Дмитрий КожевниковInversion of Control в деталях, Дмитрий Кожевников
Inversion of Control в деталях, Дмитрий Кожевников
 
«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин
«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин
«Используем неизменяемые данные и создаем качественный код», Игорь Кудрин
 
«Велогосипед», Данил Ильиных
«Велогосипед», Данил Ильиных«Велогосипед», Данил Ильиных
«Велогосипед», Данил Ильиных
 
«Процесс создания продукта», Максим Берёзкин
«Процесс создания продукта», Максим Берёзкин«Процесс создания продукта», Максим Берёзкин
«Процесс создания продукта», Максим Берёзкин
 
«Вывод продукта на новых территориях», Елизавета Алексеенко
«Вывод продукта на новых территориях», Елизавета Алексеенко«Вывод продукта на новых территориях», Елизавета Алексеенко
«Вывод продукта на новых территориях», Елизавета Алексеенко
 
Манипулятор на Ti Stellaris Launchpad, Лёша Романенко
Манипулятор на Ti Stellaris Launchpad, Лёша РоманенкоМанипулятор на Ti Stellaris Launchpad, Лёша Романенко
Манипулятор на Ti Stellaris Launchpad, Лёша Романенко
 
Лабиринт на Arduino, Вадим Ипполитов
Лабиринт на Arduino, Вадим ИпполитовЛабиринт на Arduino, Вадим Ипполитов
Лабиринт на Arduino, Вадим Ипполитов
 
«Хоба-хоба и в продакшн», Женя Пономарёв
«Хоба-хоба и в продакшн», Женя Пономарёв«Хоба-хоба и в продакшн», Женя Пономарёв
«Хоба-хоба и в продакшн», Женя Пономарёв
 
«Бегущий по лезвию. Продуктовые сценарии в дизайне», Макс Карпылев
«Бегущий по лезвию. Продуктовые сценарии в дизайне», Макс Карпылев «Бегущий по лезвию. Продуктовые сценарии в дизайне», Макс Карпылев
«Бегущий по лезвию. Продуктовые сценарии в дизайне», Макс Карпылев
 
«Роль исследований в формировании продуктового видения компании», Лиза Алексе...
«Роль исследований в формировании продуктового видения компании», Лиза Алексе...«Роль исследований в формировании продуктового видения компании», Лиза Алексе...
«Роль исследований в формировании продуктового видения компании», Лиза Алексе...
 
«Тестируем веб приложения», Павел Сташевский
«Тестируем веб приложения», Павел Сташевский«Тестируем веб приложения», Павел Сташевский
«Тестируем веб приложения», Павел Сташевский
 
«Открытая веб картография», Илья Таратухин
«Открытая веб картография», Илья Таратухин«Открытая веб картография», Илья Таратухин
«Открытая веб картография», Илья Таратухин
 
Матвей Мальков «Ещё один поиск контактов на Android»
Матвей Мальков «Ещё один поиск контактов на Android»Матвей Мальков «Ещё один поиск контактов на Android»
Матвей Мальков «Ещё один поиск контактов на Android»
 
Распределенные приложения и Azure Service Bus
Распределенные приложения и Azure Service BusРаспределенные приложения и Azure Service Bus
Распределенные приложения и Azure Service Bus
 

Олег Годовых «Страх и ненависть в Event Bus»

  • 1. СТРАХ И НЕНАВИСТЬ В EVENT-BUS Олег Годовых
  • 2.
  • 3.
  • 4. AT FIRST IT WAS LIKETHIS
  • 6. МАГАЗИНЧИК • 500 страниц документации. • В том числе 200 страниц описания API. • Большое количество сложных use-cases. • Разветвлённая логика и схема зависимостей.
  • 7. МАГАЗИНЧИК • 4 человеко-года на каждую платформу (iOS,Android). • 6 разработчиков в команде Android. • Общий размер команды — до 27 человек. • ≈40000 строк кода.
  • 8. ОСОБЕННОСТИ • Android 4.0+ • Одно действие — один запрос. • Настройками кэширования занимается сервер. • Ссылки для последующих запросов приходят с сервера.
  • 9. ПРОБЛЕМЫ • Много разнородных запросов (около 100 в последней версии API). • Компонент-инициатор != компонент-получатель. • Инициаторов может быть несколько. • Получателей тоже!
  • 10. КАК ДЕЛАТЬ ЗАПРОСЫ • In-place AsyncTask. • AQuery и иже с ними. • Сервисы, контент-провайдеры, броадкасты… • Реактивное программирование.
  • 11. ЧЕМ ПЛОХИ ASYNCTASK • Очень сложно переиспользовать. • Очень много boilerplate-кода. • Гроб, гроб, кладбище, утечка контекста. requestDataTask = new AsyncTask<Void, Void, JSONObject>() { @Override protected JSONObject doInBackground(Void... params) { final String requestResult = apiService.getData(); final JSONObject json = JsonUtils.parse(requestResult); lruCache.cacheJson(json); return json; } };
  • 13. ПОЧЕМУ НЕ КАТИТ AQUERY • Слишком локальное применение. • Опять же — много повторяющегося кода. • Сложно прикручивать другие библиотеки. aq.ajax("http://example.com", String.class, CACHE_TIME, new AjaxCallback<String>() { @Override public void callback(String url, String object, AjaxStatus status) { Type listType = new TypeToken<List<User>>() {}.getType(); List<User> list = new Gson().fromJson(object, listType); listener.onResponse(list); } });
  • 14. AsyncTask AQuery Понятность + + Удобство -1 2 Переисполь зование — — Пацаны так делают? — ≈
  • 15. ДАВАЙТЕ ПОСЛУШАЕМ GOOGLE IO • Храним в БД • Скачиваем сервисом • Отдаём через ContentProvider
  • 16. ЧТО НЕ ТАК С CP • Дважды конструируем объект (при разборе результата запроса и при десериализации из БД). • Нужно инвалидировать данные. Зачем нам SQL? Нам SQL не нужен
  • 17. AsyncTask AQuery Service + CP Понятность + + ≈ Удобство -1 3 2 Переиспользо вание — — + Не делаем лишнего — + — Пацаны так делают? — ≈ +
  • 18. ГОТОВЫЙ ФРЕЙМВОРК • Сильная связность • Есть явная «точка сопряжения» final Subscription subscription = createApiRequestObservable() //создали Observable с запросом .timeout(TIMEOUT_IN_SECONDS, TimeUnit.SECONDS) //поставили таймаут .retry(RETRY_COUNT_FOR_REQUEST) //поставили кол-во повторов .onErrorResumeNext(createRequestErrorHandler()) // назначили обработчик ошибки .map(createJsonMapOperator()) //модифицировали Observable, чтобы получать JSONObject .onErrorReturn(createJsonErrorHandler()) //возвращаем в случае ошибки то, что ожидаем .doOnNext(createCacheOperation()); //кэшируем JSONObject .subscribeOn(Schedulers.newThread()) //трудоёмкое в отдельном потоке .observeOn(AndroidSchedulers.mainThread()) // обработка результата - в main thread .subscribe(subscriber); //обработчик результата
  • 19. AsyncTask AQuery Service + CP RxJava Понятность + + ≈ ≈ Удобство -1 3 2 4 Переиспользо вание — — + + Не делаем лишнего — + — ≈ Пацаны так делают? — ≈ + +
  • 20.
  • 21. VOLLEY • Несколько уровней кэширования. • Абстрагируемся от HTTP насколько возможно. • Очень гибкое управление очередью.
  • 22. ТИПИЧНАЯ СХЕМА ДЕЙСТВИЙ • Создаём по действию новый запрос • Добавляем его в очередь • Забываем • … • ОТВЕТ СЕРВЕРА!!!
  • 23. ОТВЕТ СЕРВЕРА • Распространяется через event bus. • Все желающие его получают. • Не страшно, если никому он уже не нужен.
  • 24. НИ КАПЕЛЬКИ НЕ СТРАШНО
  • 25. OTTO • Подписка на события через аннотации. • Подписались на то, что не приходит — не страшно. • Приходит то, на что не подписывались — не беда! public class BaseFragment extends Fragment { protected Bus bus = AzbukaApplication.getBus(); @Override public void onResume() { super.onResume(); bus.register(this); NetworkFacade.cancelOldRequests(this); } @Override public void onPause() { super.onPause(); bus.unregister(this); NetworkFacade.markToCancel(this); }
  • 26. ЧЕМ МАНИПУЛИРУЕМ • BaseRequest — инкапсулирует парсинг и рассылку сообщений • BaseResponse — bean + id public static class PutUserNickRequest extends BaseRequest<PutUserNickResponse, NewUserNick, PutUserNickError> { /** * API v0.36 p. 74, Change user password (4.10.4) * @param url - POST /user/<user-id>/phone * @param nick - typed nick */ public PutUserNickRequest(String url, String nick) { super(Method.PUT, url, PutUserNickResponse.class, PutUserNickError.class, new NewUserNick(nick)); } }
  • 27. ПОДПИСКА • Нам не важно, кто отправил. • Нам нужно лишь уметь обрабатывать данный тип ответа. • Кто на экране — тот и главный! @Subscribe public void onResponse(BasketRequest.BasketContentResponse basketContentResponse) { loadWelcome(); } @Subscribe public void onError(OtherError error) { if (TextUtils.isEmpty(error.getMessage())) { Toast.makeText(getActivity(), getString(R.string.failed), Toast.LENGTH_LONG).show(); } else { Toast.makeText(getActivity(), error.getMessage(), Toast.LENGTH_LONG).show(); } }
  • 28.
  • 29. LET IT CRASH • Есть одна точка получения данных об ошибке. • Есть один общий workflow обработки ошибки. • При особой надобности — можем подписаться на ошибки конкретного класса.
  • 30. ПОДВОДНЫЕ КАМНИ • Event bus хорош, когда всё в нём хорошо. • Отладка — снежный ком.
  • 31. ПЛЮСЫ И ПЛЮШКИ • Лёгкая проверка работоспособности back-end. • Часть приложения сделана как конечный автомат на основе Event Bus. • Архитектура «непривязанных запросов» отлично ложится почти на любое приложение.
  • 32. СПАСИБО ЗА ВНИМАНИЕ А ещё я в твиттере есть, меня @0leGG зовут, там 0 как нолик, а не как Олежка.