Аспекты удачной архитектуры мобильных приложений

Очень часто приступая к разработке приложения мы, под давлением менеджера берем один из распространенных паттернов разработки и быстро кодим, чтобы получить живой прототип за день-другой. Вроде все работает, уходит в прод и все довольны.

Вот только потом, когда встает вопрос о поддержке, рефакторинге и введении новых фич оказывается, что в контроллерах у нас тонны кода, количество boilerplate застилает 4к экран, а вкорячивать новые фишки сложнее, чем переписать все снова. И вот вы уже снова перепиливаете все в стиле *уяк-*уяк и в продакшн…

А может стоило выделить время и выбрать не просто модную, а подходящую вашей задаче архитектуру?

558d941160d64fd98966bf418739ec95.jpg

Под катом ответы на распространенные вопросы и некоторые советы, которые помогут создать качественный продукт.

Встречайте!

3b13bb714fd545d7a8f59941f5c173da.pngЕвгений Мацюк. Ведущий разработчик «Лаборатории Касперского». Имеет огромный опыт внедрения новых подходов и инструментов.

cfda572f8980422790277d8aaa3d5498.pngАлександр Блинов. В REDMADROBOT занимается архитектурой Android, вопросами технологизации команды и непосредственно разработкой приложений.

fdd89992b289409d8c32367e89058608.pngАнтон Руткевич. Работая в «Яндексе», разрабатывал приложения, занимался нетривиальными случаями их сборки и процессами непрерывной интеграции. Сейчас в Juno занимается разработкой Android приложений на Kotlin.

Об архитектуре, планировании и команде

— Чем отличается удачная архитектура от неудачной?

Евгений Мацюк: Удачная архитектура дает шанс разработчикам никогда не проводить глобальный рефакторинг всего приложения. Максимум — изолированно переделать некоторые модули без долгой починки появившихся багов.

На самом деле, это дорогого стоит, так как вы можете беспрерывно и не снижая темпов «запиливать новые фичи». Приложение будет расти, набор функций увеличиваться, а у вас по-прежнему будет чувство радости от того, что «все, черт побери, логично и просто».

Александр Блинов: Архитектурные ошибки весьма коварны. Первые несколько месяцев разработки они прячутся за вашей спиной и иногда напоминают о себе костылями и подозрительным кодом. С ростом кодовой базы они начинают фигурировать все чаще, увеличивая энтропию вашего кода. Со временем внедрение новых фич несет изменения в самых неожиданных местах программы. Такие ситуации негативно влияют на настрой команды и существенно бьют по бизнесу.

— Какой, на ваш взгляд, оптимальный состав команды для разработки приложения? Сколько проектировщиков могут быть заняты разработкой архитектуры? Как выстраивать их взаимодействие для достижения максимального эффекта?

Евгений Мацюк: Если мы говорим о разработке приложения под конкретную платформу, то обычно все сводится к следующей схеме. Команда — 3–5 разработчиков разного уровня и тимлид, на котором висят задачи планирования и взаимодействия со всем внешним миром. Непосредственно архитектурными задачами может заниматься как сам тимлид, так и, например, самый сильный разработчик из команды. То есть за архитектуру ответственен один, максимум два человека. Все ключевые решения по проекту — только через них. Никто, конечно же, не отменяет холиваров внутри команды, но ответственность всегда кто-то должен нести.

Александр Блинов: Команды с большей численностью должны быть разделены на отделы, работающие над разными частями приложения. Деление на части может быть как горизонтальным, так и вертикальным. Порядок взаимодействия логических юнитов приложения должен определять архитектор. В его обязанность также входит общее проектирование системы. За соблюдением этих практик следит лид каждого из отделов.

Антон Руткевич: На мой взгляд, это сбалансированный коллектив, где есть люди с разными ролями. Безусловно, все должны хорошо разбираться в языке, платформе, архитектуре, но отличные команды получаются, когда у каждого есть какая-то любимая область в разработке в которой он разбирается особенно хорошо, «специализация» что-ли, и эти специализации не имеют большого перекрытия в команде (хотя какое-то, конечно, имеют). Специализациями могу быть, например, высокоуровневая архитектура, работа с UI или другими фреймворками платформы, CI, тестирование, дизайн. Это не значит, что только «специалисты» занимаются этими областями, но обычно именно они двигают вперед, приносят улучшенные подходы, развивают свои области. Поэтому чем больше областей охвачено — тем в больших аспектах проекта будет порядок. Если вся команда болеет за архитектуру и не любит копаться в UI фреймворке — есть большой шанс иметь частые архитектурные холивары и сделанные «кое-как» UI слои.

Также очень важно, чтобы был один, а лучше несколько человек, которые занимаются интеграцией с внешним миром. И это тоже должно им нравиться. Согласовать API с соседними командами, проверить бизнес требования с технической точки зрения, вести какие-то переписки, которые неминуемо возникают.

И еще. Если в команде нет человека, без которого разработка встанет, то очень просто уходить в отпуск, брать day-off при необходимости. Вы не представляете, как приятно работать в команде, где всегда знаешь, что коллеги подхватят твои задачи при необходимости, и это не будет проблемой.

— Какой объем времени должен быть выделен на планирование и архитектуру приложения в сравнении с остальными этапами разработки?

Александр Блинов: Главное не забывать вообще его выделять. Зачастую менеджеры подгоняют команду выпустить первый релиз как можно раньше, чтобы заработать лояльность клиента/акционеров, и обещают последующий редизайн. Но как назовешь лодку, так она и поплывет: приложение, в котором архитектура не продумана, замедляет разработку и наносит впоследствии большой урон компании.

Достаточно важно продумать общую для всей компании гибкую архитектуру, под эгидой которой будут стартовать все новые приложения. Единый подход к коду позволяет быстро запускать новые проекты, а также безболезненно увеличивать состав или проводить ротацию команды.

Евгений Мацюк: Еще важно отметить, что, если вы занимаетесь разработкой прототипов, экспериментальных приложений, то количество времени, потраченное на архитектуру, должно равняться нулю. Но в этом случае вы должны донести до менеджера, что данный продукт является только прототипом и не подлежит расширению.

Роль сервера

— Можно ли объяснять проблемы в архитектуре мобильного приложения некачественным API сервера? Или же это независимые вещи?

Евгений Мацюк: Правильной архитектурой удастся инкапсулировать некачественное API сервера.

На моей практике был такой случай. Я занимался внедрением модуля чата в банковское приложение. Работа чата осуществлялась посредством стороннего сервиса. Модуль я реализовал по концепции «Чистой архитектуры», покрыв все юнит-тестами. Сделал и забыл.

А через девять месяцев прилетает вводная, что нечего нам басурманскими сервисами пользоваться, будем использовать свои, родные. Мы получили новый сервис с абсолютно другим немного сыроватым API и другой концепцией. А переходить на этот сервис нужно прямо сейчас. Да и еще необходимо было поддержать работу прежнего сервиса, чтобы в случае чего мы могли бы переключить чат на него.

И вот тогда я испытал то бесценное чувство, когда заложенная архитектура «просто тащит». Это бесценный момент. Всем желаю такое испытать. Круче первого поцелуя.
На уровне Репозитория подмена не получилась, так как концепция нового сервиса просто другая. Поэтому подмена была осуществлена на уровне Интерактора. Да, мне пришлось реализовать новый Репозиторий и новую имплементацию Интерактора. Но вьюшку и презентер я вообще не трогал, а там много кода тоже было. Подмена сервисов чата легко осуществлялась через дагеровский модуль (просто подставляли нужную реализацию Интерактора).

Репозиторий и Интерактор я реализовывал посредством TDD. Для реализации сложной бизнес-логики TDD очень хорош, кстати. Собственно, запустил я приложение на проверку уже в самом конце, когда все было готово, чтобы просто удостовериться, что все работает. Никаких дополнительных багов и прочего не появилось. Все зло инкапсулировано. Ну здорово же?

— Как вы относитесь к методологии TDD? Какой подход к разработке вы используете чаще всего и почему?

Антон Руткевич: TDD — отличная методология. Если следовать ей, проблема покрытия кода тестами исчезает как класс, т.к. без тестов кода просто нет.

С другой стороны, при решении объемной задачи, требующей написания большого количества нового кода, бывает сложно с первого раза набросать правильную архитектуру и, тем более, продумать точно API взаимодействия между модулями. В таких случаях, опять же, на мой взгляд, TDD подход неоправданно увеличивает время разработки, т.к. перед переписыванием кода нужно переписать еще и тесты.

Поэтому мы используем TDD в основном когда нужно расширять существующий функционал и интерфейсы более менее ясны.

— Когда оправдан перенос логики выполнения из приложения на сервер?

Александр Блинов: Мобильное приложение является тонким клиентом и не предназначено для выполнения серьезной логики. Если заказчик не готов предоставить мобильному клиенту API, соответствующий данному подходу, мы встраиваем в цепь взаимодействия клиент-сервер middleware.  Middleware — это наш прокси-backend, который берет на себя интеграцию со сложными сервисами заказчика и приведение API для клиентского приложения к удобному виду. Как правило, это ускоряет разработку, так как сложная логика пишется один раз на мидле, а не два раза: на Android и iOS. В некоторых случаях встраивание в цепь middleware невозможно, например мобильные банки имеют повышенные требования к безопасности и хотят свести поверхность возможной атаки к минимуму. В этих случаях мы интегрируем наш middleware в сервера заказчика.

— Какое место занимает MVP, MVC и MVVM в архитектуре мобильных приложений?

Евгений Мацюк: Термин MVC звучит уже как-то не модно среди андроид-разработчиков. Сразу же срабатывает ассоциативный ряд с Activity, которое раньше считалось Controller и достигло нереальных размеров и сложности. Вспомнили? Передернуло от ужаса? Не произносите эту аббревиатуру вслух больше никогда, иначе будете преданы анафеме.

MVP, MVVM — это больше про Presentation слой. Причем набирает популярность в последнее время именно MVVM, но реализованный не через DataBinding, а «руками» через RxJava. В итоге получается меньше boilerplate кода, чем с MVP. С удовольствием послушаю доклад Дениса Неклюдова и Степана Гончарова про данный подход.

А «Clean architecture» — это про все приложение в целом.

О структуре Android-приложений

— В чем особенность разработки архитектуры приложения для android?

Евгений Мацюк: Вопрос, о котором можно говорить вечно. По мне самая главная особенность — это то, что сначала об архитектуре, как таковой, вообще не думали. Гугл в свое время предоставил SDK и сказал разработчикам: «В добрый путь, ребята». И ребята пошли, но не совсем по доброму пути. В итоге появилось большое количество приложений, которые приходится поддерживать и переделывать. Зато нам никогда не скучно.

Александр Блинов: Разработчиками Android было принято много довольно странных решений, таких как: жизненный цикл, способ предоставления пермишенов. В первых версиях системы такие решения были продиктованы низкой мощностью железа. В настоящее время смартфоны стали куда более мощными, однако мы стали заложником лозунга: «Написали однажды — страдаем всегда!». Это порождает создание фреймворков, инкапсулирующих в себя борьбу с системой, таких как наш с Senneco Moxy. Советую послушать рассказ Юры на Мобиусе о том, как устроено Moxy под капотом

— Можно ли не писать лишнего? Какие слои ядра обязаны быть в приложении с удачной архитектурой, а какие могут быть исключены в ряде случаев?

Александр Блинов: Это довольно холиварный вопрос. Пять логических слоев, которые мы выделяем в «Чистой архитектуре», имеют свою определенную область ответственности. Мы придерживаемся консистентности в архитектуре и, даже если в какой то фиче потребность в логическом слое отсутствует, он будет выступать в качестве прокси. Это делает код предсказуемым и легко расширяемым.

— Какой стек технологий обычно применяется для проектирования приложения под Android?

Евгений Мацюк: В прошлом своем выступлении я рассказывал про следующий стек: RxJava, Dagger, Unit-тесты. Сейчас добавил бы Moxy — для обработки жизненного цикла, Cicerone — для навигации. А вообще еще можно начать писать на Kotlin.

Александр Блинов: В REDMADROBOT аналогичный стек технологий. Kotlin у нас в продакшене находится больше года. Весь новый код пишется только на Kotlin.

— Какой бы главный совет вы дали разработчикам в плане построения архитектуры?

Антон Руткевич: Я бы сказал, что нужно помнить о SOLID и осознанно применять подход Clean Architecture. Это не значит, что нужно параноидально следовать ему везде, но отход от Clean Architecture в каких-то местах всегда должен быть осознанным и взвешенным решением.

Евгений Мацюк: Думайте. Пробуйте. И еще раз думайте. И еще раз пробуйте.
Обязательны изучите основные паттерны проектирования и проникнитесь, зачем и в каких ситуациях они действительно нужны.

Создание удачной архитектуры — самое сложное и ответственное занятие. Но тут действительно уместна поговорка — «терпение и труд — все перетрут».

Александр Блинов: Не забывайте уделять время архитектуре. Смело закладывайте ее в оценку проекта и донесите до менеджеров, что отсутствие правильно выстроенной архитектуры впоследствии нанесет удар по бизнесу.

— О чем вы будете рассказывать на Мобиусе?

Евгений Мацюк: Мы хотим произвести погружение в «Чистую архитектуру». Рассмотрим основные вопросы, которые задают разработчики, рассмотрим кейсы, которые часто встречаются в нашей жизни, и покажем, как их решать в «Чистой архитектуре».

К сожалению, у нас только 50 минут, и мы не расскажем и малой доли того, что накопилось у нас интересного. Но мы работаем над документом (это будет или серия статей, или CookBook), в которой постараемся раскрыть «Чистую архитектуру» от базовых теоретических моментов до самых изощренных практических ситуаций. Поэтому мы будем рады любой помощи, любому совету, любой интересной задаче. С января нами запущен чат в «Телеграме», посвященный архитектуре в Андроид. Нас уже более 500 человек. Присоединяйтесь и задавайте свои вопросы!

Антон Руткевич: На Мобиусе расскажу о том, как осознанно писать код так, чтобы после написания его гарантированно можно было покрыть тестами. Несмотря на то, что в докладе будут примеры на Kotlin (чтобы код влезал в слайд) и Android, акцент будет на идеях, которые лежат вне платформ и языков, и на практическом умении применять их в любом контексте.  Поэтому приглашаю всех.

Александр Блинов: Многие технологии отлично работаю на Helloword-ах, но столкнувшись с реальным кодом терпят фиаско. В своем докладе мы разберем самые сложные кейсы, на которых «Чистая архитектура» доказала свою состоятельность!

Поэтому хочется пригласить всех на наш с Евгением доклад в рамках Mobius 2017.  Обещаем погружение в Чистую архитектуру и славный холивар с товарищами по цеху! Также желаем каждому из вас выйти с конференции вдохновленным, с горящим глазами и крутыми идеями!

До встречи на форуме!

Комментарии (0)

© Habrahabr.ru