Разработка под Android как реализовать сложные функции за ограниченное время

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

Я расскажу, как я анализирую пользовательскую историю, проектирую и реализую решение, а также готовлю запрос на слияние.

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

Знакомство с функцией

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

И я имею в виду все , а не только детали реализации.

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

 


 

Записи типа «загрузить данные» пока подходят. Позже я буду беспокоиться обо всех деталях (получение данных из API, локальное кеширование, обработка ошибок и т. Д.).

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

Принятие решений (но только тех, которые вам нужно)

Затем, со всеми перечисленными высокоуровневыми требованиями, я выбираю некоторые общие детали решения.

Здесь я выбираю, какие компоненты навигации я хочу использовать (в текущем проекте Android мы используем Activity или Fragment, в зависимости от случая) или в какой модуль должен входить код (в нашем случае модули Gradle).

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

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

Другой вариант - быстро запрограммировать грубую реализацию и обсудить «незавершенную работу» пул-реквест - наличие конкретного примера облегчает обсуждение. 

Делать одно дело за раз

Приняв все необходимые решения, я создаю функциональную ветку для всей истории. Я называю его «OA-5» (мы используем ключи задач JIRA в качестве имен веток).

Затем я выбираю ОДИН элемент (т. Е. Загружаю данные) из списка и создаю подветвь для размещения реализации, например «OA-5_load_data».

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

Второй критерий, который я использую, - начать с архитектурного уровня, который диктует правила: 

  • Я бы начал со слоя, который формирует другие интерфейсы (в нашем случае - уровень домена), или 

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

Помимо этого, я выбираю то, что хочу реализовать в данный момент.

Разбиение подзадачи на более мелкие части

В другом списке (назовем его подсписком) я отмечаю более мелкие шаги, которые необходимо сделать для завершения пункта «загрузка данных». Подсписок пока не обязательно должен быть полным.

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

Я стараюсь, чтобы эти элементы были достаточно маленькими, чтобы их было легко реализовать. Например, «загрузить данные в модель просмотра» на данный момент охватывает только получение записей из интерактора.

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

Использование TDD помогает мне эффективно работать с такими мелкими элементами, потому что я могу тестировать их изолированно, не запуская все приложение.

Сохранение кода простым

При написании кода я стараюсь сделать его максимально простым, сосредотачиваясь на текущих требованиях и расширяя их по мере необходимости.

Такой подход помогает мне избежать чрезмерной инженерии.

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

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

Упрощение проверки кода

Я следую этому шаблону, пока у меня не закончатся элементы в подсписке.

Затем я готовлю запрос на перенос из подчиненной ветви в функциональную ветку: «OA-5_load_data» -> «OA-5». Таким образом, рецензенты могут просмотреть весь код небольшими частями, которые легче усвоить.

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

После объединения всех частей я создаю еще один запрос на перенос - на этот раз в ветку разработки: «OA-5» -> «develop». В этом случае рецензенты могут только бегло просматривать код, в основном ища оставшиеся настройки разработчика (ненужные журналы, ярлыки навигации и т. Д.), Поскольку они уже видели весь код раньше.

После объединения этого пул-реквеста функция готова для контроля качества.

Адаптация процесса к вашему случаю

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

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

Как вы могли заметить, этот процесс основан на TDD, описанном Кентом Беком в статье «Разработка через тестирование: на примере». Эта книга, которую я очень рекомендую, определенно изменила мой стиль работы, хотя прошли годы, прежде чем я начал писать тесты.

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




Контакты

+38 (093) 647-37-31

pavel.keepwarning@gmail.com

Ришельевская, 33, Одесса, Украина

Блог

Оставьте заявку
и мы Вам перезвоним