Comments 19
Я уж думал, что в русскоязычном сообществе Android разработчиков эта тема никого не интересует. Статья хорошая, но два небольших момента:
Пишите ещё :)
- debounce — это не директива, а оператор, в терминологии Rx
- Введённые интерфейсы в данном примере — интерфейсы ради интерфейсов, никакого смысла вводить их без нескольких реализаций нет, а рефакторинг в IDE позволяет легко сделать это при необходимости
Пишите ещё :)
0
Ну, если так судить, то почему тогда Вас не смущает самое наличие MVP в примере без тестов?) Абстракция ради абстракции ведь! Подумаешь, тот же код из onCreate, но раскидали по классам с модными названиями, зачем пыжились? Нет, если я правильно думаю и автор не угомонит свои таланты, то нас ждут логичные продолжения с DI и тестами, где как раз и заиграют красками интерфейсы. По крайней мере, я очень на это надеюсь, потому что начало хорошее, а пробуя писать тесты для Rx в последний раз я чувствовал боль.
+1
Ну как бы, ничего не мешает писать тесты без интерфейсов, конечно, если вы не будете объявлять все методы как final, если говорить о юнит тестах с моками (mockito, например).
Логичные продолжения с DI, да, было бы не плохо просветить людей, особенно, если это будет Dagger 2.
Тесты с Rx пишутся на раз два, гораздо удобнее, чем для коллбек-ориентированной асинхронщины, т.к. вы можете выполнить Observable в текущем потоке — toBlocking().
Ваш стиль наезда меня позабавил, спасибо :)
Логичные продолжения с DI, да, было бы не плохо просветить людей, особенно, если это будет Dagger 2.
Тесты с Rx пишутся на раз два, гораздо удобнее, чем для коллбек-ориентированной асинхронщины, т.к. вы можете выполнить Observable в текущем потоке — toBlocking().
Ваш стиль наезда меня позабавил, спасибо :)
+1
Когда-то однажды наткнулся на интересную библиотеку github.com/ogaclejapan/RxBinding
0
А какие-то чуть более примитивные примеры использования rx в Android может кто-нибудь привести? Я догадываюсь, что в интерфейсе Idea без этого явно не обошлось. Но большинство задач ui: ввести что-то -> отправить на сервер и загрузить что-то -> отобразить. Зачем rxJava в подобных задачах?
+1
Вы можете решать эти задачи, используя RxJava, будет элегантно (особенно с лямбдами) и дополняемо/изменяемо.
0
Задача работы с сетью в рамках android-а предполагает наличие отдельного патока и его правильного старта, учитывающая повороты, закрытие экрана. Далее идут задачи по обработке отсутствие сети (как, в общем-то, было указано в статье) и т.д
Все выше сказанное проистекает из одного факта, задача ввести что-то -> отправить на сервер и загрузить что-то -> отобразить не является такой уж тривиальной, как может показаться на первый взгляд.
Все выше сказанное проистекает из одного факта, задача ввести что-то -> отправить на сервер и загрузить что-то -> отобразить не является такой уж тривиальной, как может показаться на первый взгляд.
+2
Так как Model и View используют одни и тебе виджеты (в нашем случае EditText и TextView) для своей работы, разумно будет реализовать содержащий их класс.ExampleViewHolder.java:
Недопустимо ссылаться на виджеты равно как на любую UI или Presenter специфик логику из модели, теряется весь смысл концепции MVP. В идеале части M V и P разделены на отдельные модули и имеют односторонние зависимости M <= P <= V.
0
В данном случаи ссылаются на одни и те же UI элементы конкретные реализации, поэтому действительно фраза не совсем верная, хотя дальше видно по примеру что имелось ввиду.
По поводу разделение — оно делается, что бы представить программу в простом линейном виде: получение данных -> обработка данных -> отображение данных
Так как UI элементы в данном случаи будут выступать и как источник данных и элементы для отображение, то ссылки естественно возникают в реализации Model и View, Presenter связывает Model с View.
В итоге получаем схему:
По поводу разделение — оно делается, что бы представить программу в простом линейном виде: получение данных -> обработка данных -> отображение данных
Так как UI элементы в данном случаи будут выступать и как источник данных и элементы для отображение, то ссылки естественно возникают в реализации Model и View, Presenter связывает Model с View.
В итоге получаем схему:
Presenter {
Model model = ...
View view = ...
onCreate(...) {
model.getData(...).flatMap(...).subscribe(view.show());
}
}
0
Так как UI элементы в данном случаи будут выступать и как источник данных и элементы для отображение, то ссылки естественно возникают в реализации Model и View, Presenter связывает Model с View.
Нет, это уже не MVP и с ним общего ничего не имеет, кроме названий классов. Что вы будете делать, когда вам понадобится сделать версию под планшет, где, предположим, из-за особенностей UI придётся использовать совсем другие виджеты? Т.е. я ставлю вас перед фактом, что надо поддерживать два набора View с разным набором виджетов. Как вы это организуете в вашем варианте?
+1
Если мы говорим о действительно разном наборе виджетов, что чем вас не устраивает самый тривиальный вариант:
?
Model model = isTable ? new TableModelImpl(...) : new PhoneModelImpl(...)
View view = isTable ? new TableViewImpl(...) : new PhoneViewImpl(...)
Presenter presenter = new Presenter(model, view);
?
0
Конечно, Presenter presenter = new PresenterIml(model, view);
0
DrVirtual прав, нельзя знать про особенности View в модели, вообще. Модель — это слой логики, который работает с данными (в вашей доменной области).
Суть модели именно в том, что она может быть использована откуда угодно, а значит не должна знать специфики таких вещей, как View.
Делать две версии модели из-за особенностей Ui — нарушение DRY и здравой логики.
Суть модели именно в том, что она может быть использована откуда угодно, а значит не должна знать специфики таких вещей, как View.
Делать две версии модели из-за особенностей Ui — нарушение DRY и здравой логики.
0
Так в Model вы и не знаете про View ни чего. Две реализации только в том случаи если вы имеете два разных виджета т.е в первом случаи вы получаете текст запроса из edittext-а, а во втором из spinner-а, при этом интерфейс доступа к данным у вас один и тот же, а каждая реализация оборачивает свои UI элементы в Model, представляя общий интерфейс доступа к данным.
0
Ваше представление об MVP в корне неверно. Либо вы читали такие же некорректные статьи, либо некорректно интерпретировали. У вас даже на КДПВ нет ссылки от Model к View. Хотя и она неверна, т.к. связи должны быть односторонними, а в обратную сторону работа идёт через интерфейсы.
Вы обманываете, т.к. эти ваши
Я не занимаюсь разработкой под Android, но в идеальном варианте ни Model, ни Presenter не имеют доступа ни то, что к View, но и к пакету android в принципе, т.е. они не знают, что работают под android'ом. И уж особенно нельзя нарушать правила разделения зависимостей между M, V и P — код в разных модулях и зависимости между ними настроены односторонне M<=P<=V, это принципиально.
MVP это про распределение обязанностей и зависимостей, в вашем случае реализация примера должна иметь следующий вид:
Пакет Model:
класс с данными ExampleModel
Пакет Presenter:
интерфейс ExampleView с методом updateResponse(String response)
класс ExamplePresenter'а с методами doRequest(String response)
Пакет View:
класс-реализация интерфейса ExampleView
ExampleView дёргает ExamplePresenter.doRequest, ExamplePresenter устанавливает в ExampleModel данные запроса, и делает запрос на сервер, когда получает ответ, то устанавливает его в ExampleModel и дёргает метод интерфейса ExampleView.updateResponse.
Также важно выделять весь View в отдельный пакет и обращаться только через интерфейсы, т.к. это позволит делать unit тесты, подменив реализации на тестовые.
150 человек добавило эту статью в избранное — кто-то мог воспринять её серьёзно. Рекомендую удалить её пока, ознакомиться с темой более внимательно и написать действительно полезную статью. В качестве хорошей реализации MVP рекомендую ознакомиться с реализацией на www.mvcsharp.org (она на c#, но смысл от этого не меняется). Плюс там есть несколько статей на эту тему. Можете консультироваться, если будут вопросы.
Так в Model вы и не знаете про View ни чего
Вы обманываете, т.к. эти ваши
edittext-а, а во втором из spinner-а— это часть View.
каждая реализация оборачивает свои UI элементы в Model, представляя общий интерфейс доступа к данным.
Я не занимаюсь разработкой под Android, но в идеальном варианте ни Model, ни Presenter не имеют доступа ни то, что к View, но и к пакету android в принципе, т.е. они не знают, что работают под android'ом. И уж особенно нельзя нарушать правила разделения зависимостей между M, V и P — код в разных модулях и зависимости между ними настроены односторонне M<=P<=V, это принципиально.
MVP это про распределение обязанностей и зависимостей, в вашем случае реализация примера должна иметь следующий вид:
Пакет Model:
класс с данными ExampleModel
Пакет Presenter:
интерфейс ExampleView с методом updateResponse(String response)
класс ExamplePresenter'а с методами doRequest(String response)
Пакет View:
класс-реализация интерфейса ExampleView
ExampleView дёргает ExamplePresenter.doRequest, ExamplePresenter устанавливает в ExampleModel данные запроса, и делает запрос на сервер, когда получает ответ, то устанавливает его в ExampleModel и дёргает метод интерфейса ExampleView.updateResponse.
Также важно выделять весь View в отдельный пакет и обращаться только через интерфейсы, т.к. это позволит делать unit тесты, подменив реализации на тестовые.
150 человек добавило эту статью в избранное — кто-то мог воспринять её серьёзно. Рекомендую удалить её пока, ознакомиться с темой более внимательно и написать действительно полезную статью. В качестве хорошей реализации MVP рекомендую ознакомиться с реализацией на www.mvcsharp.org (она на c#, но смысл от этого не меняется). Плюс там есть несколько статей на эту тему. Можете консультироваться, если будут вопросы.
0
Sign up to leave a comment.
Android. Пару слов об MVP + rxJava