Не так давно количество пользователей приложений превышало количество пользователей в Интернете. Многие веб-компании осознали это и начали поддержку приложений. Как лучше всего масштабировать эту мобильную разработку?

Серверная часть для мобильных клиентов

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

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

Как мы знаем, мобильный телефон - это не Интернет, поэтому его дизайн и логика отличаются от Интернета. Чтобы учесть различия, мобильный клиент должен реализовать тонну логики для преобразования полезной нагрузки из серверной веб-службы перед ее использованием.

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

Задняя часть для передней части (BFF)

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

Достоинств этой модели немного.

  1. Мы могли бы использовать существующих квалифицированных разработчиков в веб-серверной части для работы в мобильной серверной части.
  2. Мы могли бы перенести часть логики и решений, необходимых для стороны мобильного клиента, на серверную часть мобильного устройства, сократив объем работы, необходимой для мобильного клиента.
  3. Если бы мы были тщательно разбиты и сконструированы, мы могли бы сделать мобильный клиент более динамично управляемым изменениями из мобильной серверной части без необходимости выпускать новую версию приложения для каждого обновления.

Эта модель известна как задняя часть для передней части (BFF).

Контракт между серверной частью и клиентом

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

Чтобы уменьшить накладные расходы, мы могли бы рассмотреть возможность использования обычного генератора моделей (например, Apache Thrift, Protocol Buffers и т. Д.). Генераторы моделей позволяют генерировать коды моделей для различных платформ (например, серверный JavaScript, Android Java, iOS Swift), которые можно совместно использовать и передавать.

Имея это место, мы бы:

  1. Уменьшите необходимость создания отдельных кодов моделей на разных платформах.
  2. Уменьшите риск ошибки из-за различий в интерпретации модели.
  3. Если мы тщательно создадим модель, мы потенциально сможем напрямую сопоставить модель с представлением клиента, уменьшая необходимость преобразования модели в представление клиента.

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

Разработка модульных приложений

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

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

Такая модель даст больше:

  • Противоречивые изменения, делающие рецензирование кода более сложной задачей
  • Личная заинтересованность в чужом коде, поскольку они находятся в одном модуле и могут быть связаны
  • Потенциально плохая архитектура, которая, возможно, нарушает граничные правила, поскольку нет четких границ между кодами (все может получить доступ ко всему)
  • Увеличенное время сборки, так как изменения в модуле должны перекомпилировать гигантский модуль.

Модульность и разделение ответственности

Разработка приложений может быть модульной как для Android, так и iOS. Ниже приведен рекомендуемый способ разбиения. Он разделен на три слоя.

Примечание. На приведенную ниже модель ссылается исходное предложение Google по использованию Instant App, как указано здесь.

  1. Модуль координатора
  2. Функциональные модули
  3. Базовый модуль

Примечание. Если вам интересно, как подключить зависимости (в Android), вы можете обратиться к Настройка модулей Android с помощью Dagger 2.

Модуль координатора

Это координатор уровня приложения. На этом уровне работа заключается в координации логического потока на уровне приложения между функциями. Он может иметь свой собственный интерфейс или представление (действие, фрагмент, ViewController и т. Д.) В качестве основных представлений записи и потенциально отвечает за логику навигации между функциями.

Группа здесь также может нести ответственность за работу по непрерывной интеграции (CI). Вероятно, это улучшит инструмент в целом, объединяя в цепочку все остальные модули для создания полного приложения, а также весь процесс выпуска.

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

Базовый модуль

Это модуль, который определяет все необходимые согласованные архитектурные шаблоны, которых должна придерживаться каждая группа. В нем могли быть:

  • Соответствующие интерфейсы / протокол для групп функций для реализации и следования пакету. У него будет базовая ссылка на элемент, связанный с дизайном (например, общий цвет, виды, текст и т. Д.).
  • API для доступа к различным системам или требованиям уровня приложения, применимым ко всем функциям (например, сетевой клиент, репозиторий, аналитика, аутентификация и т. Д.)
  • Общие служебные программы, которые понадобятся каждой группе функций и которые будут использоваться (например, различные функции расширения, тестовые классы)
  • Совместное использование общих внешних библиотек, используемых всеми функциями

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

На схеме я просто показываю один базовый модуль. Однако при необходимости можно разделить на несколько базовых модулей с разными наборами обязанностей.

Функциональные модули

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

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

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

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

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

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

Прочие соображения

Избегайте компромисса между преимуществом платформы и единообразием

В мобильной разработке есть iOS и Android. Хотя они похожи, они во многом отличаются. В идеале мы должны сделать их как можно более последовательными, чтобы развитие было более плавным.

Однако у каждой платформы есть свои преимущества и проблемы. Android имеет свои проблемы обработки жизненного цикла и внедрения зависимостей. Модульность iOS более утомительна с CocoaPods по сравнению с Gradle для Android. Язык тоже разный (например, Swift и Kotlin). В Android есть компонент архитектуры, а в iOS его нет. iOS выпустила SwiftUI, но Android по-прежнему полагается на кодовую базу XML.

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

Ограничьте создание универсальной кроссплатформенной разработки

Я бы поддержал кроссплатформенное обучение. Разработчику Android всегда полезно знать что-то об iOS, и наоборот.

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

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

В структуре домашнего кодекса

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

Это может показаться полезным, поскольку теперь мы можем перераспределить веб-разработчиков для мобильной работы. Хотя теоретически это звучит хорошо, на практике это просто невозможно.

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

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

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

По возможности используйте промышленные библиотеки и наборы инструментов

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

Библиотеки загрузки изображений, сетевые библиотеки, структуры DI и среды реактивного программирования - вот некоторые примеры отличных инструментов, которые мы могли бы использовать. Это означает, что не следует избегать использования Dagger 2 в Android только потому, что в iOS нет этой структуры, если только Dagger 2 не приносит свои преимущества в работу с Android.

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

Заключение

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