Pull to refresh

Comments 48

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

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

P.S. Есть канал по паттернам, где 90% обсуждений посвящено MVP, можно присоединяться :)
Спасибо за комментарий и канал по паттернам! Менеджмент подписки и использование лоадеров тема для отдельной статьи, везде есть свои плюсы и минусы)
UFO just landed and posted this here
Чего минусите то человека? Дело говорит. Посмотрите на количество файлов и связность.
Ну, заявиться и сказать, что кг/ам (образно), — дело плевое.
А вот привести конкретную аргументацию на ресурсе, который посещают в том числе и новички, — силушки не хватило :)
UFO just landed and posted this here
Нарисуете свою схему именно для этого примера?
Я не умею рисовать схемы (шутка) =) Но на словах: зачем три файла/класса для презентера? Зачем интерфейс Presenter (если там lifecycle callback методы, то и назовите его LifecycleCallbacks по аналогии с ActivityLifecycleCallbacks)? А абстрактный BasePresenter, чтобы от CompositeSubscription отписываться? Увеличение абстракции оправдано, если вы пишете какой-нибудь фреймворк или библиотеку. Или это делается потому что так написано в статьях по MVP? Задайте себе вопрос: как часто вам приходилось выкидывать один презентер и заменять его на другой? Мне, например, ни разу.
Что касается Model слоя: приложение вообще ничего не должно знать о сущностях DTO, DBO а так далее. Это все лучше вынести в, так называемый, Repository слой. В котором выполняются мапинги данных, принятия решений о том, откуда эти данные брать (из кэша, БД или сети) и так далее. Наружу торчит только Observable<List> getRepoList(String name);

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

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

А вот по сущностям в модели можно обсудить.
Вы предлагаете жёстко привязаться к модели данных.
Возьмём за пример модель RepositoryDTO — в реальности это большая модель с большим количеством полей.
В этом примере слою View надо всего лишь 4 поля. Для этого создаётся отдельный ViewObject — Repository(не путать с вашим паттерном) который содержит только нужные поля, тем самым абстрагируясь от RepositoryDTO и от модели вообще.
Можно предположить, что в будущем измениться апи, скажем c GitHub на GitLab.
В текущем примере нужно поменять маппер Model <->ViewObject. В вашем менять View.
Вы меня неправильно поняли. Я как раз об этом и говорил. Есть некоторые сущности, которые являются ViewObject, при этом откуда она была получена, нам абсолютно неважно. Получение же этого ViewObject логично вынести в слой, который я назвал Repository, роль которого в контексте статьи выполняет ApiInterface. Просто я предлагаю скрыть всю реализацию мапингов и прочих манипуляций внутри реализации ApiInterface и наружу выдавать уже готовые ViewObject модели. В статье же это делается на уровне презентера.
getRepoList() { 
    return retrofit.getRepoList().flatMap({Model -> ViewObject});
}
Я понял, можно, но это если View чётко соответсвует одной модели, а если нет?
Например, есть 2 Активити, которым нужна одна модель, но разные поля из неё т.е. для разных View, ViewObject будут разные, хоть и будут абстрагировать одну модель.
У вас получится, что слой Repository будет иметь методы getViewObject1() и getViewObject2().
В примере автора, о конкретном ViewObject будет знать только соответствующая конкретная реализация Presenter, что на мой взгляд несколько правильнее.
Спасибо за замечания!
1) Интерфейс Presenter в данный момент получился лишним, с этим я полностью согласен.
2) Абстрактный BasePresenter содержит в себе функцию управления подпиской, реализовывать это в каждом презентере = дублировать код.
3) Model слой и DTO. Тут палка о двух концах, с одной стороны независимость приложения от DTO, DBO и прочих моделей (которая в данный момент достигается за счет мапперов), с другой стороны жесткая связка Model (DataRepository) и прикладного приложения.
В данный момент в слое Model нет ни одного импорта из Presenter или View, мы можем перенести весь слой в другое приложение, он полностью независим. Также, как было сказано выше, при изменении model нужно переписать мапперы, View Object (а вместе с ними и остальной код) при этом не изменятся.
Расскажите как надо, с удовольствием посмотрим и обсудим!
UFO just landed and posted this here
Честно не понял, о чём вы?) А если поменять формат передачи данных в примере на XML, то к чему ваш комментарий будет относиться?
Надо всем внимательно посмотреть на такой проект Google как JSONNET.

Маленький нюанс: Jsonnet — это не проект гугла. Вот вам цитата:

Jsonnet is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.
UFO just landed and posted this here
Хорошо, я спрошу иначе, как формат передачи данных относится к архитектуре и взаимодействию между компонентами внутри приложения?
UFO just landed and posted this here
Опишите идею в контексте, в данном случае, MVP и Android.
UFO just landed and posted this here
Для начала оффтоп — чтобы ответить на комментарий есть кнопка «Ответить», не нужно писать новый каждый раз.
Далее, вы куда-то уходите от идеи, C# тут появился уже:)… можете дать конкретный пример, ссылки?
Скажем есть база данных, простейшая. Есть экран со списком и с кнопкой, по нажатию идёт запрос в базу и заполняется список.
Какие ноды куда мне надо привязывать?
UFO just landed and posted this here
Шизофрения какая-то в комментах пошла…
Ну я очень хотел понять, о чём говорил товарищ babylon :) Но комментом выше он решил слиться.
UFO just landed and posted this here
Согласен, как ни старался, так и не понял причем тут JSON и архитектура.
UFO just landed and posted this here
babylon похоже вы комментарии не в той статье пишите. Здесь разговор про Android+MVP, а вы говорите о JavaScript Object Notation, JSONNET и т. д.
UFO just landed and posted this here
Товарищ, вы пишете, совершенно не разбираясь в теме. Каким образом то, что возвращает rest api поможет построить архитектуру android-приложения? Вы предлагаете в java вместо классов для модели хранить все в json? Не говоря об отвратительной скорости работы с этим (по сравнению с POJO), как вообще json может заменить нормальные, человеческие java-классы?
Дайте пример?) Или вы, сударь, трепло?)
UFO just landed and posted this here
Классы те же объекты, только избыточные.

Wat??
Плохо приспоcбленные для разборки и сборки. Поэтому выдуваются всяческие костыли в виде DI.

Как связаны dependency injection и сборка/расборка объектов? Что такое вообще сборка объектов?
Причём тут REST API????

При том, что в статье идет речь о запросах к api, которые возвращают json.
Ощущение, что вы понятия не имеете о разработке на java и под android. Или просто троллите всех.
И да, используйте кнопку «Ответить».
UFO just landed and posted this here
JSONPath этот ваще для школоты, а от XPath аж тошнит.
Стоит упомянуть, что пьяным заходить на хабр не стоит. Причем здесь дисплей-листы? Это вообще поприще компьютерной графики.

Скрытый текст
А на гитхабе у jsonpath читаем:
If you configure JsonPath to use the JacksonMappingProvider you can even map your JsonPath output directly into POJO's.

Как он мог такое предложить, объекты — это же фу-фу-фу, слой модели должен состоять из json-ов!
UFO just landed and posted this here
Экась вы ловко со слоя model на view перескочили. Точно тролль.
То есть, вы gui на чистом opengl реализовываете? Понятно, почему вы такой нарезанный. Вас остается только пожалеть.
Но все же вернитесь к нашим баранам json-ам, если вам есть, что сказать по существу. И загляните под спойлер предыдущего сообщения. Или это вы так ловко обходите неприятные вам углы?
UFO just landed and posted this here
Вот мне чисто для себя — вы разницу между Java и JavaScript улавливаете? Или canvas андроидовый? Ну, тогда вообще все очень плохо.
UFO just landed and posted this here
Вы не нервничайте — и не будете промахиваться по кнопке «Ответить» :) Это ведь не удобно, вот вам пример)
По делу, официальную документацию к чему надо читать? Открыл документацию по Андроиду — вашу тему не нашёл.
UFO just landed and posted this here
Честно говоря, я давно так не смеялся читая комментарии :)
Sign up to leave a comment.