Pull to refresh

Comments 25

Чем вам не угодила архитектура которую предлагает гугл?
Похоже, я еще не очень хорошо изучил Android, поскольку не знаю что за архитектуру предлагает гугл.
Расскажи подробнее.
Он и так предлагает полный MVP. View это xml файлы. Activity это Presenter. Модель это контент провайдеры. Не нужно изобретать велосипеды.
То что вы описали это не полный MVP.
В такой ситуации у View или Presenter-а нет интерфейса, который можно симитировать.
А контент провайдер не является моделью, потому что туда нельзя добавить методы бизнес-логики, которые обычно и живут в модели.
Контент провайдер можно рассматривать как репозиторий, который достает модель из БД.

Поэтому я и затеял этот цикл статей, чтобы показать как существующие в Android компоненты увязать в MVP.
Если вы не забыли android это мобильная ОС и ресурсы тут ограничены. Так что не надо плодить интерфейсы.
Не согласен с тем, что не надо плодить лишние интерфейсы.
Как показывает практика, рост размеров проекта и замедление работы приложения, при использовании MVP, на глаз заметить не возможно.
А вот скорость разработки и качество очень даже заметны.
это верно, для обычных приложениях, а не на мобильных платформах
У меня есть мобильное приложение, сделанное с использованием MVP.
Если отбросить 550кб звукового файла, то ее размер примерно 250 кб.
Без использования MVP и вспомогательных технологий, полагаю ее размер был бы 50 кб.

Итого.
1. Увеличение объема на 200 кб из-за дополнительных библиотек (а не в 5 раз, как может показаться)
2. Приложение работает на эмуляторе и на моем Galaxy S работает быстро, во всяком случае я быстрее могу настроить необходимые параметры, чем в других аналогичных программах. Расходов по скорости нет.

То есть расходы 200 Кб.

Зато доходы:
1. Качественная разработка. Для написания движка я написал порядка 30 тестов, и при отладке часто через тесты обнаруживал, что сломал предыдущую часть алгоритма.
2. Без тестов у меня бы ушло примерно в два-три раза больше времени на полную отладку алгоритма, а ошибки, при этом, находили бы пользователи, что очень плохо.

То есть доходы примерно двоекратное сокращение времени разработки и репутация качественного софта.

Для меня доходы многократно превышают расходы.
Тесты это хорошо. Но паттерны вы по моему мнению используете не по назначению.

Если я не ошибаюсь, ваше приложение это будильник. А теперь представьте, что вам нужно написать приложении с интерфейсом посложнее, содержащее 5+ активити с не самой простой логикой перехода между ними. В этом случае, исходя из ваших двух статей, вам придется городить пакеты под каждую активити, писать презентеры и интерфейсы. Количество классов быстро станет over 9000. И работать такой энтерпрайз монстр станет гораздо медленне.

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

Для тестов UI есть несколько хороших фреймворков, посмотрите в сторону Robotium и Robolectric. Также мне советовали вот эту книгу.

P.S. Окончательный размер приложения зависит больше от его ресурсов, чем от лишних классов. Без использования MVP и вспомогательных технологий размер вашего приложения стал бы ненамного меньше.
Даже если это большое приложение, то в проект приложения на одну активность надо добавить 1 интерфейс для View, 1 presenter, 1 интерфейс для модели и 1 класс модели.
Конечно файлов 5 файлов больше чем один, но кода в этих файлах больше всего лишь на 5-10%

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

Еще раз скажу, что на скорости работы это заметно не скажется.

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

Поэтому в большом проекте использование MVP наоборот принесет еще больше пользы.

Спасибо за ссылки на тестовые framework-и, я их обязательно посмотрю.
Но польза от тестирования UI принебрежима мала по сравнению с возможностью тестировать части приложения изолированно от других, а это можно делать и через встроенный в Eclipse JUnit.

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

Использование MVP решает все эти проблемы.

Скорость разработки и качество возрастают гораздо значительнее чем увеличивается размер программы.

P.S.
Не согласен что отказ от MVP сделал бы мое приложение намного меньше. В мое приложение добавилось 200кб библиотек для RoboGuice. Но в остальном MVP требует только 5-10% увеличение кода что не является критичным для работы программы.
RoboJuice — фреймворк, позволяющий использовать аннотации и dependency injection? В чем было его преимущество для вашего проекта? Я не работал с этим фреймворком, но похоже что внутри него лежит рефлекшн, а это довольно затратный механизм.

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

Ничто не мешает вам тестировать UI отдельно от логики. Тестируйте UI специализированными фреймворками либо встроенными в сдк классами, как это описано здесь, а для логики пишите unit testы.
Да, основная задача RoboGuice это Dependency Injection.
Так же я его использую для инициализации экземпляров классов.
Он действительно использует рефлексию.
Вот только это нельзя назвать «довольно затратным». Видимых просадок производительности нет. Лишняя 0.1 секунды при старте активности это не затратно.

Никак не могу понять почему приложение станет громоздким. Если у меня 20 активностей, которые сосредоточены в 20 пакетах, это разве громоздко? Какой критерий при определении громоздкости вы используете?

Как мне в тесте отделить UI от логики? Я знаю как это можно сделать через Dependency Injection. Расскажите другой способ.

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

Тестировать UI вместе с логикой — плохо, потому что нельзя разрабатывать логику и UI по одтельности.

Ктому же встроенный в SDK JUnit Test Framework обладает существенным недостаткам: он не поддерживает изоляцию тестов. То есть первый тест поднимает процесс приложения и тестирует первую активность. Второй тест берет приложение в том состоянии, которое осталось после первого теста и тестирует вторую активность. Если у вас есть в приложении многопоточноть то вы будете полуать завершение потоков из перой активности во время тестирования второй. Так же некторые события UI задерживаются и приходят во вторую активность.

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

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

Почему нельзя вынести логику в отдельные классы, не зависящие от интерфейса и тестировать их юнит тестами?

Согласен, что при проектировании можно расположить UI и логику в разных классах и передавать имитации в тестируемый класс логики через конструктор или еще как-то.

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

Кстати, а как вы в своих тестах имитируете окружение при тестах классов с логикой?

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

Признаю, что я был не прав когда говорил, что нельзя тестировать логику без UI. Но способы имитации окружения, вроде передачи имитаций через конструктор выглядят для меня очень неудобными. Слишком много нужно дополнительного кода, по сравнению с использованием Dependency Injection
Ну я как бы стараюсь не передавать контекст в классы логики. Пытаюсь делать их изолированными от UI.
Не очень хорошо изучить Android и написать статью о разработке под Android — это путь на тёмную сторону силы, о юный джедай :)
Джедай тегом source пользоваться должен.
Спасибо тебе, добрый человек. Теперь поправил.
А что с Mock Frameworkами? Или вы тестируете не андроид java-машине?
Для тестов с помощью android-junit проекта есть Android-Mock — порт Easymock'а.
Я использую AndroidMock, который, как заметил helions8, является подгонкой EasyMock под андроид.
В результате я тестирую приложения в Dalvik на эмуляторе, или же на своем смартфоне.
А другие не пробовали? Вроде PowerMock?
PowerMock я не пробовал использовать.
Но думаю попробовать в следующем проекте, потому что у AndroidMock есть несколько серьезных недостатков, да и не развивается он.
Я использую AndroidMock, который, как заметил helions8, является подгонкой EasyMock под андроид.
В результате я тестирую приложения в Dalvik на эмуляторе, или же на своем смартфоне.
Sign up to leave a comment.

Articles