Паттерн MVP
— шаблон, который впервые появился в IBM, а затем использовался в Taligent в 1990-х. MVP является производным от MVC, при этом имеет несколько иной подход. В MVP представление не тесно связано с моделью, как это было в MVC. На следующей диаграмме показана структура MVP:
Как видно на этой диаграмме, Presenter занял место контроллера и отвечает за перемещение данных, введенных пользователем, а также за обновление представления при изменениях, которые происходят в модели. Presenter общается с представлением через интерфейс, который позволяет увеличить тестируемость, так как модель может быть заменена на специальный макет для модульных тестов. Также как и для MVC, давайте рассмотрим структуру MVP со стороны бизнес-логики приложения:
В данном случае структура MVP аналогична MVC в том плане, что код доступа к данным находится вне этой модели, а вся бизнес-логика приложения концентрируется в модели (эта схожесть подтверждает то, что MVP является производным от MVC, изменилась только логика представления).
Давайте рассмотрим пример приложения WPF использующего MVP, аналогичный тому, что был рассмотрен в предыдущих статьях (на примере приложения выбора проектов). Конечная структура приложения показана на следующей UML-диаграмме:
Представление использует класс ProjectsView который реализует интерфейс IProjectsView. ProjectsView и IProjectsView содержат все необходимые методы для обновления представления и связи с Presenter, который в свою очередь содержит ссылки на прототипы интерфейсов IProjectsView и IProjectsModel в виде переменных ProjectsPresenter.view и ProjectsPresenter.model. Такая конструкция обеспечивает взаимосвязь между моделью и представлением через Presenter.
Подобная модель обладает лучшей тестируемостью нежели модель MVC, т.к. мы перенесли логику построения представления в Presenter (в MVC представление строилось непосредственно из модели).
Давайте теперь соберем это приложение (оно будет работать аналогично рассмотренному ранее приложению MVC).
Модель
Создайте новый проект WPF в Visual Studio, добавьте ссылку на сборку ProjectBilling.DataAccess, которая рассматривалась в статье RAD и Monolithic. Данная сборка реализует код доступа к данным и во всех рассмотренных проектах остается одинаковой. Добавьте класс ProjectsModel со следующим содержимым:
Класс модели ProjectsModel реализует интерфейс IProjectsModel со следующими членами:
Представление
Представление реализовано в файлах ProjectView.xaml и ProjectView.xaml.cs:
Presenter
Presenter включает в себя следующий код:
Здесь используются следующие обработчики событий:
Главное окно приложения MainWindow.xaml просто позволяет запустить несколько окон с представлением ProjectsView:
Запустив это приложение, вы получите аналогичный результат, как и для MVC рассмотренного ранее. Главный интерес здесь представляет только структура Presenter, который используется в MVP.
Итак, MVP представляет собой большой шаг вперед по сравнению с MVC в нескольких направлениях:
MVP обеспечивает проверяемость состояния и логики представления, перемещая их в Presenter.
Представление жестко отделяется от модели, при этом связь организуется через Presenter. В отличие от MVC, MVP допускает повторное использование бизнес-логики без непосредственного видоизменения модели (за счет использования интерфейса IView). Например, если вы захотите перенести это WPF-приложение на Silverlight, вам потребуется только создать представление в Silverlight, реализующее IProjectsView, а IProjectsPresenter и IProjectsModel можно использовать повторно.
Паттерны для новичков: MVC vs MVP vs MVVM
Добрый день, уважаемые коллеги. В этой статье я бы хотел рассказать о своем аналитическом понимании различий паттернов MVC, MVP и MVVM. Написать эту статью меня побудило желание разобраться в современных подходах при разработке крупного программного обеспечения и соответствующих архитектурных особенностях. На текущем этапе своей карьерной лестницы я не являюсь непосредственным разработчиком, поэтому статья может содержать ошибки, неточности и недопонимание. Заинтригованы, как аналитики видят, что делают программисты и архитекторы? Тогда добро пожаловать под кат.
Ссылки
Введение
Во времена, когда солнце светило ярче, а трава была зеленее, на тот момент команда студентов, как автор этой статьи, разрабатывали программное обеспечение, писав сотни строк кода непосредственно в интерфейсе продукта. Иногда использовались сервисы и менеджеры для работы с данными и тогда решение получалось с использованием паттерна Document-View. Поддержка такого кода требовала колоссальных затрат, т. к. нового разработчика надо обучить (рассказать), какой код за что в продукте отвечает, и ни о каком модульном тестировании и речи не было. Команда разработки — это 4 человека, которые сидят в одной комнате.
Прошло время, менялась работа. Разрабатываемые приложения становились больше и сложнее, из одной сплоченной команды разработчиков стало много разных команд разработчиков, архитекторов, юзабилистов, дизайнеров и PMов. Теперь каждый ответственен за свою область: GUI, бизнес-логика, компоненты. Появился отдел анализа, тестирования, архитектуры. Стоимость разработки ПО возросла в сотни и даже тысячи раз. Такой подход к разработке требует наличие стойкой архитектуры, которая бы синхронизировала разные функциональные области продукта между собой.
Паттерны
Учитывая цель уменьшения трудозатрат на разработку сложного программного обеспечения, предположим, что необходимо использовать готовые унифицированные решения. Ведь шаблонность действий облегчает коммуникацию между разработчиками, позволяет ссылаться на известные конструкции, снижает количество ошибок.
По словам Википедии, паттерн (англ. design pattern) — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.
Начнем с первого главного – Model-View-Controller. MVC — это фундаментальный паттерн, который нашел применение во многих технологиях, дал развитие новым технологиям и каждый день облегчает жизнь разработчикам.
Впервые паттерн MVC появился в языке SmallTalk. Разработчики должны были придумать архитектурное решение, которое позволяло бы отделить графический интерфейс от бизнес логики, а бизнес логику от данных. Таким образом, в классическом варианте, MVC состоит из трех частей, которые и дали ему название. Рассмотрим их:
Модель
Под Моделью, обычно понимается часть содержащая в себе функциональную бизнес-логику приложения. Модель должна быть полностью независима от остальных частей продукта. Модельный слой ничего не должен знать об элементах дизайна, и каким образом он будет отображаться. Достигается результат, позволяющий менять представление данных, то как они отображаются, не трогая саму Модель.
Представление (View)
В обязанности Представления входит отображение данных полученных от Модели. Однако, представление не может напрямую влиять на модель. Можно говорить, что представление обладает доступом «только на чтение» к данным.
Различия MVC & MVVM & MVP
Рассмотрим и сравним каждый из них.
Model-View-Presenter
Данный подход позволяет создавать абстракцию представления. Для этого необходимо выделить интерфейс представления с определенным набором свойств и методов. Презентер, в свою очередь, получает ссылку на реализацию интерфейса, подписывается на события представления и по запросу изменяет модель.
Реализация:
Каждое представление должно реализовывать соответствующий интерфейс. Интерфейс представления определяет набор функций и событий, необходимых для взаимодействия с пользователем (например, IView.ShowErrorMessage(string msg)). Презентер должен иметь ссылку на реализацию соответствующего интерфейса, которую обычно передают в конструкторе.
Логика представления должна иметь ссылку на экземпляр презентера. Все события представления передаются для обработки в презентер и практически никогда не обрабатываются логикой представления (в т.ч. создания других представлений).
Пример использования: Windows Forms.
Model-View-View Model
Данный подход позволяет связывать элементы представления со свойствами и событиями View-модели. Можно утверждать, что каждый слой этого паттерна не знает о существовании другого слоя.
Реализация:
При использовании этого паттерна, представление не реализует соответствующий интерфейс (IView).
Представление должно иметь ссылку на источник данных (DataContex), которым в данном случае является View-модель. Элементы представления связаны (Bind) с соответствующими свойствами и событиями View-модели.
В свою очередь, View-модель реализует специальный интерфейс, который используется для автоматического обновления элементов представления. Примером такого интерфейса в WPF может быть INotifyPropertyChanged.
Пример использования: WPF
Model-View-Controller
Основная идея этого паттерна в том, что и контроллер и представление зависят от модели, но модель никак не зависит от этих двух компонент.
Реализация:
Контроллер перехватывает событие извне и в соответствии с заложенной в него логикой, реагирует на это событие изменяя Mодель, посредством вызова соответствующего метода. После изменения Модель использует событие о том что она изменилась, и все подписанные на это события Представления, получив его, обращаются к Модели за обновленными данными, после чего их и отображают.
Пример использования: MVC ASP.NET
Резюме
Реализация MVVM и MVP-паттернов, на первый взгляд, выглядит достаточно простой схожей. Однако, для MVVM связывание представления с View-моделью осуществляется автоматически, а для MVP — необходимо программировать
MVC, по-видимому, имеет больше возможностей по управлению представлением.
Общие правила выбора паттерна
Заключение
Большое спасибо за уделенное время, приятного чтения!
Model-View-Presenter — компромисс и универсальный рецепт
Аббревиатуру MVP можно интерпретировать по разному, но в статье речь пойдет не о спорте.
В сети есть большое количество статей по архитектурным паттернам для iOS и Android разработчиков, и по MVP в частности. Иногда паттерн рассматривается в контексте обеих платформ. Кто-то выбирает данный паттерн для улучшения тестируемости своего кода, кто-то использует его в основном для разделения кода представления от модели. Также встречаются решения, которые используют MVP для унифицирования кода платформ, при условии что разработчики в компании владеют данными технологиями. Но общих слов и выводов иногда недостаточно для разработчика-прагматика. При проектировании коммерческих приложений неизбежно возникает множество деталей, которые общая архитектурная концепция не может раскрыть, и нельзя сказать, что есть единственное каноническое решение.
В статье я постараюсь описать ситуации, с которыми очень часто сталкиваются мобильные разработчики на реальных проектах, и когда действительно стоит задуматься о переходе на архитектурный паттерн более сложный чем “One UIViewController (Activity) to rule them all”. Или лучше сказать, когда нам это будет выгодно. Далее речь пойдет о компромиссе между временем и сложностью разработки в реалиях “обычных” проектов, которые в основном приходят на оценку и разработку.
Введение
Большинство мобильных проектов для нативных SDK сейчас являются клиент-серверными приложениями. В свою очередь такие приложения по сложности системы и времени жизни могут сильно отличаться. Есть приложения “однодневки” для работы в рамках одного мероприятия или ежегодного праздника, после которого они никому не нужны. Есть и серьезные проекты, требующие большого процента покрытия кода тестами, для обеспечения стабильной работы при внесении изменений разными участниками команды.
Какие проекты являются “обычными” можно определить по следующим критериям:
Сравнение MVP с паттернами по умолчанию
Рассмотрим самый простой паттерн, а именно iOS MVC с пассивной моделью, который является по сути жесткой связкой слоев представления и модели, где вся логика находится в UIViewController-е. Аналогичный подход получается и на Android-е, если вы пишите свои проекты по руководству из видеоуроков для начинающих или с большинства обучающих сайтов.
Если сравнить его с MVP, то основным отличием является класс Presenter, в который мы выносим логику обработки событий, форматирования данных и управления View. Под View мы будем понимать слой, включающий дочерние классы UIViewController, Activity или Fragment и их связку с классами всевозможных контролов. Таким образом мы “разгружаем” классы аналогичные UIViewController от тех обязанностей, которыми они не должны заниматься, оставляя внутри только код инициализации представлений и анимаций.
Как это часто бывает, в течение разработки первой версии приложения дополнительно добавляются функциональности, связанные с недостаточной проработкой ТЗ. Иногда изменения настолько радикальны, что приходится переписывать бОльшую часть уже проделанной работы. Наиболее часто встречается ситуация, когда просят добавить дополнительное поле к сущности и отобразить отформатированную информацию. Проследим какие классы мы изменим в проекте при добавление нового UI-элемента, отображающего отформатированную дату:
Очевидно, что мы усложнили систему введением паттерна MVP, так как количество классов, которые подверглись изменению при простом добавлении нового свойства сущности у нас возросло. Отдельно стоит отметить, что при реализации MVP создают отдельный интерфейс для View и пытаются сделать так, чтобы в Presenter-е находилось как можно меньше кода, связанного с платформой и не было прямых ссылок на конкретных наследников UIViewController, Activity или Fragment, потому что иначе будет соблазн написать код представления непосредственно в Presenter-е.
Для небольших и слабо подверженных изменениям проектов, подход без четкого отделения представления от бизнес логики наоборот является, на мой взгляд, лучшим, так как существенно сокращает время разработки. Небольшой проект обычно пишет один человек, а количество кода не составит труда другому участнику команды разобраться в течение нескольких часов с задачей и внести изменения, если это требуется.
В поиске компромисса
Встает логичный вопрос, а зачем же все усложнять?
Во-первых, для того, чтобы четко распределить ответственность между классами. Это особо актуально, если вы являетесь участником команды разработки. Важно понимать, что никто из программистов не мыслит одинаково. Например, код форматирования даты из примера в итоге может оказаться как в ячейке таблицы, так и в контроллере, так и в коде класса, отвечающего за маппинг данных, пришедших с сервера.
Таких деталей, помимо форматирования, в вашем проекте может встретиться немало. Можно привести более сложный пример с отображением в элементе списка составной модели представления, которая собирается по частям из закэшированных данных. Всю работу по форматированию и подготовку модели для представления мы переносим в Presenter, поэтому неоднозначности в том, где форматировать данные, не остается.
Не стоит путать модель представления в данной статье с ViewModel из MVVM, название лишь указывает на сущность, хранящую отформатированную и готовую к показу во View информацию.
При использовании обычного подхода мы, скорее всего, разместили бы код составления модели для ячейки в наследнике UIViewController-е или Activity (Fragment-е), что повлекло за собой увеличение кода в классе, в котором и так намешано немало, связанного с функционированием представления.
Написание “полезных” интеграционных тестов также становится возможным с вводом MVP, где основным объектом тестирования выступает Presenter. Конечно, используя только юнит-тестирование, можно протестировать используемые в приложении компоненты, которые являются God-объектами и наследниками UIViewController или Activity (Fragment), но это будет не вполне эффективно.
Рассмотрим момент, связанный с расширением проекта. Дополнительные фичи на проект могут приходить не сразу же после релиза первой версии, поэтому важно, чтобы среди разработчиков были приняты конвенции по тому, как писать код. MVP в данном случае выступает набором правил, которые можно четко описать на следующей диаграмме:
Небольшие уточнения к диаграмме:
Здесь выявляется единственный недостаток описываемой вариации MVP, а именно то, что сервис разрастается в пределах одного класса-файла. Если в iOS мы можем использовать категории и расширения для разделения одного большого класса-сервиса, то в Java придется разбивать сервис на классы подсервисы для работы с конкретным экраном.
Если у вас не более 20-25 API методов, то код остается читаемым в рамках одного файла, при условии правильного форматирования и комментирования. Для первой версии продукта можно описывать всю логику получения и отправки данных в пределах одного класса. Но не стоит увлекаться, так как технический долг со временем будет увеличиваться.
Поскольку представление можно отделить от модели, то вам не составит труда показать заказчику свою работу, пусть и со статичными данными, в случае, если бэкенд еще не готов или работает нестабильно. Благо, есть множество способов замОкать серверную часть. Если бэкендом занимается независимая команда, то при наличии согласованной документации можно быть более менее уверенным в том, что при появлении настоящего сервиса для вас не окажется неожиданностью, какие поля шлются в API, и вы успеете отладить часть, связанную с форматированием данных для представления.
Без документации, я бы все таки остановил разработку на этапе создания дизайна экранов и выводом тестовых данных на основе моделей представления. В этом случае вы также получите более менее функциональный интерфейс пригодный для демо, но самое главное вы не потратите много времени на изменение сущностей для подгонки их под реальное API, так как Presenter выступит в роли адаптера, в котором будет осуществляться преобразование данных от сервиса в форматированные данные модели представления.
Универсальность
Другим плюсом использования паттерна MVP является его универсальность для iOS и Android. Если у вас большое количество проектов разрабатывается под обе платформы, то логика Presenter-а будет универсальной, и если разработка приложений происходит по очереди, то адаптация на другой платформе будет проходить быстрее и предсказуемее, так как код логики в Presenter-е практически одинаковый. Более того, на этапе начала работы по адаптации для другой платформы уже будут готовые тест-кейсы. Конечно, если вы удосужились потратить время и написать их.
Следующим преимуществом использования паттерна MVP является разделение ресурсов разработчиков под разные платформы. Например, iOS синьор может написать часть кода под Android на уровне джуниора или мидла и быть при этом полезным, чтобы не пришлось за ним все переделывать. Сам я не сторонник “универсальных солдат”, так как лучше знать одну технологию хорошо, чем несколько на уровне джуниора или мидла. Практикующих старших разработчиков (не тимлидов или технических директоров) под обе платформы я не встречал, но не буду спорить, что такие профессионалы существуют. Основная причина дефицита таких людей, на мой взгляд, заключается в том, что в наше время очень тяжело уследить за развитием обеих технологий. Даже при условии того, что iOS и Android заимствуют некоторые конструкции друг у друга, под капотом реализация все равно разная. Но для небольших команд и “обычных” проектов подход с использованием непрофильного разработчика является вполне адекватным. Многие iOS программисты хотели бы попробовать себя в Android и наоборот. Можно отдать такому “легионеру” написать часть кода, связанного с Model или Presenter. Также будет неплохо, если человек сможет написать простой UI. Но задачи со сложными UI элементами с анимацией, оптимизацией, профилированием и многопоточностью, за исключением вызовов API сервиса, конечно, должен решать уже более опытный профильный разработчик.
Интересным случаем является тот, когда тестировщики находят баг на двух платформах сразу. Получается, что если баг в логике, то задачу можно не делить на несколько разработчиков, а отдать чинить одному человеку. При этом ему не придется сильно долго разбираться в логике разных платформ, так как используются одинаковые архитектурные решения.
Сравнение с другими известными архитектурными шаблонами
Есть еще один очень важный вопрос: почему за основу был выбран именно MVP, а не паттерны, основанные на чистой архитектуре или MVVM? В начале статьи мы постарались сконцентрироваться на том, что имеем дело с “обычными” проектами, которые желательно написать быстро, но с должным качеством и возможностью долгосрочной поддержки.
Чистая архитектура подойдет большим командам, которые имеют в штате опытных программистов под конкретную платформу, просто по причине того, что кода приходится писать в разы больше, чем в MVP, и этот код нужно правильно уметь разместить в определенном модуле.
В MVVM мы должны перестроить логику мышления на декларативную. Также MVVM очень часто ассоциируется с библиотеками Rx*, с которыми должны быть знакомы программисты, а это сразу же ставит ограничение при поиске нового разработчика, либо вы осознанно тратите время на его обучение. В этом плане MVP прозрачнее и имеет меньше ограничений на умения разработчика.
Выводы
Перейдем к выводам. Преимущества, которые нам удалось выявить для паттерна MVP, если посмотреть на него со стороны выгоды внедрения в разработку:
Подводя итоги, можно утверждать следующее: если у вас есть небольшая команда из специалистов готовых на реализацию проектов под основные мобильные платформы, вам нужны универсальные архитектурные правила, а также возможность распараллеливания задач в рамках экрана и необходимость показа демо заказчику с частично работающей функциональностью, например, если практикуются спринты, то MVP определенно ваш выбор. Дополнительным бонусом выступает удобная поддержка проекта, которая не должна привести к фразе “а вот если бы мы сейчас написали все заново” и ситуациям, когда только для того, чтобы разобраться в коде одного огромного UIViewController-а или Activity будет потрачено больше времени, чем на саму фичу.
Паттерны разработки: MVC vs MVP vs MVVM vs MVI
От переводчика: данная статья является переработкой английской статьи по паттернам разработки. В процессе адаптации на русский немало пришлось изменить. Оригинал
Выбор между различными паттернами разработки, всегда сопровождается рядом споров и дискуссий, а разные взгляды разработчиков на это еще больше усложняют задачу. Существует ли решение этой идеологической проблемы? Давайте поговорим о MVC, MVP, MVVM и MVI прагматично. Давайте ответим на вопросы: “Почему?”, “Как найти консенсус?”
Вступление
Вопрос выбора между MVC, MVP, MVVM и MVI коснулся меня, когда я делал приложение для Warta Mobile вместе с моей командой. Нам было необходимо продвинуться от минимально жизнеспособного продукта к проверенному и полностью укомплектованному приложению, и мы знали, что необходимо будет ввести какую-либо архитектуру.
У многих есть непоколебимое мнение насчет различных паттернов разработки. Но когда вы рассматриваете архитектуру, такую как MVC, то, казалось бы, полностью стандартные и определенные элементы: модель (Model), представление (View) и контроллер (Controller), разные люди описывают по разному.
Трюгве Реенскауг (Trygve Reenskaug) — изобрел и определил MVC. Через 24 года после этого, он описал это не как архитектуру, а как набор реальных моделей, которые были основаны на идее MVC.
Я пришел к выводу, что поскольку каждый проект — уникален, то нет идеальной архитектуры.
Необходимо детально рассмотреть различные способы реализации, и подумать над преимуществами и недостатками каждой.
Чего мы хотим добиться?
Масштабируемость, сопровождаемость, надежность
Очевидно, что масштабируемость (scalability) — возможность расширять проект, реализовывать новые функции.
Сопровождаемость (maintainability) — можно определить как необходимость небольших, атомарных изменений после того, как все функции реализованы. Например, это может быть изменение цвета в пользовательском интерфейсе. Чем лучше сопровождаемость проекта, тем легче новым разработчикам поддерживать проект.
Надежность (reliability) — понятно, что никто не станет тратить нервы на нестабильные приложения!
Разделение отвественности, повторное использование кода, тестируемость
Важнейшим элементом здесь является разделение ответсвенности (Separation of Concerns): различные идеи должны быть разделены. Если мы хотим изменить что-то, мы не должны ходить по разным участкам кода.
Без разделения ответственности ни повторное использование кода (Code Reusability), ни тестируемость (Testability) практически невозможно реализовать.
Ключ в независимости, как заметил Uncle Bob в Clean Architecture. К примеру, если вы используете библиотеку для загрузки изображений, вы не захотите использовать другую библиотеку, для решения проблем, созданных первой! Независимость в архитектуре приложения — частично реализует масштабируемость и сопровождаемость.
Model View Controller
У архитектуры MVC есть два варианта: контроллер-супервизор (supervising controller) и пассивное представление (passive view).
В мобильной экосистеме — практически никогда не встречается реализация контроллера-супервизора.
Архитектуру MVC можно охарактеризовать двумя пунктами:
Диаграмма иллюстрирует идеологию паттерна. Здecь, представление определяет как слушателей, так и обратные вызовы; представление передает вход в контроллер.
Контроллер принимает входные данные, а представление — выходные, однако большое число операций происходит и между ними. Данная архитектура хорошо подходит только для небольших проектов.
Пассивное представление MVC
Главная идея пассивного представления MVC — это то, что представление полностью управляется контроллером. Помимо этого, код четко разделен на два уровня: бизнес логику и логику отображения:
Massive View Controller
Нельзя трактовать Активити как представление (view). Необходимо рассматривать его как слой отображения, а сам контроллер выносить в отдельный класс.
А чтобы уменьшить код контроллеров представлений, можно разделить представления или определить субпредставления (subviews) с их собственными контроллерами. Реализация MVC паттерна таким образом, позволяет легко разбивать код на модули.
Однако, при таком подходе появляются некоторые проблемы:
Решение этих проблем кроется за созданием абстрактного интерфейса для представления. Таким образом, презентер будет работать только с этой абстракцией, а не самим представлением. Тесты станут простыми, а проблемы решенными.
Все это — и есть главная идея MVP.
Model View Presenter
Данная архитектура облегчает unit-тестирование, презентер (presenter) прост для написание тестов, а также может многократно использоваться, потому что представление может реализовать несколько интерфейсов.
С точки зрения того, как лучше и корректней создавать интерфейсы, необходимо рассматривать MVP и MVC только как основные идеи, а не паттерны разработки.
Use cases
Создание use cases — это процесс выноса бизнес логики в отдельные классы, делая их частью модели. Они независимы от контроллера и каждый содержит в себе одно бизнес-правило. Это повышает возможность многократного использования, и упрощает написание тестов.
В примере на GitHub, в login controller, вынесен use case валидации и use case логина. Логин производит соединение с сетью. Если есть общие бизнес правила в других контроллерах или презентерах, можно будет переиспользовать эти use case’ы.
Привязывание представления (View Bindings)
В реализации MVP есть четыре линейный функции, которые ничего не делают, кроме небольших изменений в пользовательском интерфейсе. Можно избежать этого лишнего кода, использовав view binding.
Все способы биндинга можно найти здесь.
Здесь простой подход: легко тестировать, и еще легче представить элементы представления как параметры через интерфейс, а не функции.
Стоит отметить, что с точки зрения презентера — ничего не изменилось.
Model View View-Model
Существует другой способ биндинга: вместо привязывания представления к интерфейсу, мы привязываем элементы представления к параметрам view-модели — такая архитектура называется MVVM. В нашем примере, поля email, password, и разметка определены с помощью связываний. Когда мы меняем параметры в нашей модели, в разметку тоже вносятся изменения.
ViewModel’и просты для написания тестов, потому что они не требуют написания mock-объектов — потому что вы меняете свой собственный элемент, а потом проверяете как он изменился.
Model View Intent
Еще один элемент, который можно ввести в архитектуре, обычно называется MVI.
Если взять какой-либо элемент разметки, например кнопку, то можно сказать, что кнопка ничего не делает, кроме того, что производит какие-либо данные, в частности посылает сведения о том что она нажата или нет.
В библиотеке RxJava, то, что создает события — называется observable, то есть кнопка будет являться observable в парадигме реактивного программирования.
А вот TextView только отображает какой-либо текст и никаких данных не создает. В RxJava такие элементы, которые только принимают данные, называются consumer.
Также существуют элементы, которые делают и то и то, т. е. и принимают и отправляют информацию, например TextEdit. Такой элемент одновременно является и создателем (producer) и приемником (receiver), а в RxJava он называется subject.
При таком подходе — все есть поток, и каждый поток начинается с того момента, как какой-либо producer, начинает испускать информацию, а заканчивается на каком-либо receiver, который, в свою очередь, информацию принимает. Как результат, приложение можно рассматривать как потоки данных. Потоки данных — главная идея RxJava.
Заключение
Несмотря на то, что внедрение разделения ответсвенности требует усилий, это хороший способ повысить качество кода в целом, сделать его масштабируемым, легким в понимании и надежным.
Другие паттерны, такие как MVVM, удаление шаблонного кода, MVI могут еще сильнее улучшить масштабируемость, но сделают проект зависимым от RxJava.
Также, следует помнить, что можно выбрать всего лишь часть из этих элементов, и сконфигурировать для конечного приложения в зависимости от задач.




