Шаблон MVC на Android

497

Можно ли реализовать шаблон модель-представление-контроллер в Java для Android?

Или это уже реализовано через Activity? Или есть лучший способ реализовать шаблон MVC для Android?

Мохит Дешпанде
источник
64
Ваш вопрос очень хороший. Но ответ, помеченный как решение, на мой взгляд, неверен. Это может ввести в заблуждение нескольких человек.
Сагар
4
Проверьте мои 2 сообщения, начиная здесь Android Architecture: MV?
Дори
1
Также существует ли дополнительный набор правил, которым нужно следовать, чтобы придерживаться MVC, или разработка Android уже адаптирована для MVC из-за Activity, XML, ресурсов?
Пламя Удуна
3
@ Дори, я исправлю твою ссылку: Android Architecture: MV?
Андрейбета
Эта статья точно соответствует тому, что вы ищете, MVC в Android на практическом примере: digigene.com/architecture/android-architecture-part-2-mvc
Али Нем

Ответы:

239

В Android у вас нет MVC, но у вас есть следующее:

  • Вы определяете свой пользовательский интерфейс в различных XML-файлах по разрешению, оборудованию и т. Д.
  • Вы определяете свои ресурсы в различных XML-файлах по локали и т. Д.
  • Вы расширяете такие предложения , как ListActivity , TabActivity и используете инфляторы XML-файла .
  • Вы можете создать столько классов, сколько пожелаете для своей бизнес-логики.
  • Для вас уже написано много Utils - DatabaseUtils, Html.
Pentium10
источник
3
@JDPekham, почему вы говорите: «Вы не можете создать экземпляр деятельности, не поговорив со своим макетом / представлением»? Создание экземпляра действия не требует общения с представлениями, фактически разговор с представлениями ни в коем случае не является частью создания экземпляра Activity. Вы МОЖЕТЕ (но не обязаны) вызывать различные методы Activity, которые взаимодействуют с вашими представлениями, когда и если вы считаете нужным. Второй вопрос: если предположить, что Activity предназначен для выполнения роли «контроллера» (я полагаю, что многие разработчики Android так считают), почему бы не поговорить со своими взглядами из Activity?
8
Для тех, кто говорит, что «Android - это MVC», попробуйте Backbone.js (да, на стороне клиента js) в течение недели, а затем вернитесь и скажите, что «Android - это MVC». Вы, наконец, поймете вопрос и почему мы продолжаем задавать вопросы :)
Марк Петерсон
14
«В Android у вас нет MVC» ???? В Android, как и на других языках, у вас есть MVC, если вы хотите MVC.
Лоренцо Барбальи
1
@LorenzoBarbagli Он имеет в виду, что Android не применяет MVC в приложениях по дизайну (как это делает iOS). Вы должны реализовать разновидность MVC, MVP или чего-то другого самостоятельно, если хотите достичь того, что обеспечивает MVC, а именно - разделения проблем и изолированной, легко тестируемой модели.
Пиовезан
Нет. В Android определенно есть MVC, но неявно. Это просто реализовано по-другому в соответствии с тем, как Android структурирует все.
6
229

Универсального паттерна MVC не существует. MVC - это концепция, а не основа программирования. Вы можете реализовать свой собственный MVC на любой платформе. Пока вы придерживаетесь следующей основной идеи, вы реализуете MVC:

  • Модель: что визуализировать
  • Вид: Как сделать
  • Контроллер: события, пользовательский ввод

Также подумайте об этом следующим образом: когда вы программируете свою модель, модель не должна беспокоиться о рендеринге (или коде, специфичном для платформы). Модель сказала бы представлению, мне все равно, будет ли ваш рендеринг Android, iOS или Windows Phone, это то, что вам нужно для рендеринга. Представление будет обрабатывать только код для конкретной платформы.

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

Рамон Чан
источник
12
Хотя это правда и хорошо сказано, это теория и люди практичны!
TWiStErRob
1
@TWiStErRob Но шаблоны проектирования - это теоретические, абстрактные идеи, у которых нет только одного способа их реализовать. Заявление: «Я не хочу понимать MVC в теории, я просто хочу, чтобы оно было реализовано», звучит для меня так, будто это может привести к тому, что «я собираюсь поставить стиральную машину на мою кухню, потому что стиральные машины реализуют шаблон Cleaner ™ и кухням это нужно ».
Лукас Юрихич
1
Я думаю, что примеры неоценимы, потому что они показывают, что придумали другие люди. Можно улучшить их и учиться на их усилиях. Не нужно, чтобы каждый заново изобретал колесо. В контексте Android и его сложного жизненного цикла существуют проблемы, которые не рассматриваются в шаблоне проектирования, но с ними сталкиваются все. Это то, что я имел в виду под практическим.
TWiStErRob
47

Действия, представления и действия на Android являются встроенным способом работы с пользовательским интерфейсом Android и представляют собой реализацию модели модель-представление-представление-модель (MVVM) , которая структурно аналогична (в том же семействе, что и модель-представление). -controller.

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

Дерик Бэйли
источник
29

После некоторого поиска наиболее разумным ответом будет следующее:

MVC уже реализован в Android как:

  1. View = layout, ресурсы и встроенные классы, подобные Buttonпроизводным от android.view.View.
  2. Контроллер = Активность
  3. Модель = классы, которые реализуют логику приложения

(Это, кстати, не подразумевает никакой логики предметной области в деятельности.)

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

PS Обратите внимание, что Activity иногда перезапускается, поэтому в нем нет места для данных модели (самый простой способ вызвать перезапуск - это пропустить android:configChanges="keyboardHidden|orientation"XML и включить ваше устройство).

РЕДАКТИРОВАТЬ

Мы можем говорить о MVC , но это будет так сказать FMVC , Framework - Model - View - Controller . Framework (ОС Android) навязывает свою идею компоненты жизненного цикла и связанных с ними событий, и на практике контроллер ( Activity/ Service/ BroadcastReceiver), в первую очередь отвечает за справиться с этим Framework -imposed событие (такие как OnCreate () ). Должен ли пользовательский ввод обрабатываться отдельно? Даже если это необходимо, вы не можете отделить его, события пользовательского ввода также приходят из Android.

Во всяком случае, меньше кода , который не Android-конкретнее вы положили в свой Activity/ Service/ BroadcastReceiver, тем лучше.

18446744073709551615
источник
3
Деятельность имеет прямой доступ к пользовательскому интерфейсу, тогда как в MVC контроллер не должен знать о представлении (только наоборот).
Конрад Моравский
2
@KonradMorawski Хммм .... Вид, зная о том, как отображать вещи и о Контроллере ? Ребенок, скажем, Buttonзная о Контролере ? Кажется более логичным, что представления знают только об отображении вещей. А учитывая, что Model знает только о природе данных, именно поэтому необходим Controller : что-то должно знать и о Model, и в View .
18446744073709551615
4
Очевидно, что представление должно знать о контроллере, чтобы делегировать события контроллеру. Контроллер отслеживает это до модели и сообщает представлению, каковы были результаты (чтобы он мог отобразить его). Контроллер не раздувает представление (в отличие от Activity), и при этом он не должен знать ничего о кнопках, текстовых полях, списках и т. Д. (Тогда как Activity знает).
Конрад Моравский
1
Я думаю, что Serviceподпадают под зонтик контроллера тоже
CL22
1
Вы когда-нибудь слышали о наблюдателях? Наилучшее разделение Iv, найденное до сих пор, это когда 1. у контроллера есть только экземпляр модели, 2. у модели нет знаний о контроллере или представлении, но представление может регистрироваться как наблюдатель модели (так что модель вроде знает о представлении, но он не знает, кто это, и он не заботится) - когда модель выполняется с загрузкой данных, он уведомляет всех наблюдателей (обычно 1) и 3. представление имеет только экземпляр модели для извлечения данных из него. Таким образом, есть только 2 зависимости для всей инфраструктуры MVC. Я думаю, что 2 является минимальным, поэтому он должен быть лучшим макетом.
Срнчек
18

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

Но, тем не менее, так как Android работает с классами и ресурсами, иногда вы даже вынуждены следовать шаблону MVC. На мой взгляд, более сложными являются действия, которые иногда отвечают за представление, но, тем не менее, одновременно выполняют роль контролера.

Если вы определяете свои представления и макеты в файлах XML, загружаете свои ресурсы из папки res, и если вы избегаете более или менее смешивать эти вещи в своем коде, то вы все равно следуете шаблону MVC.

RoflcoptrException
источник
14

Вы можете реализовать MVC в Android, но он не «изначально поддерживается» и требует определенных усилий.

Тем не менее, я лично склоняюсь к MVP как более чистому архитектурному шаблону для разработки под Android. И, говоря MVP, я имею в виду это:

введите описание изображения здесь

Я также разместил более подробный ответ здесь .

После игры с различными подходами к реализации MVC / MVP в Android, я пришел к разумному архитектурному шаблону, который я описал в этом посте: MVP и MVC Architectural Patterns в Android .

Василий
источник
14

Лучший ресурс, который я нашел для реализации MVC на Android, - это сообщение :

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

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

Эрве Доннер
источник
8
было бы здорово получить резюме, если статья будет удалена однажды.
pqsk
12

Я согласен с JDPeckham и считаю, что одного XML недостаточно для реализации UI-части приложения.

Однако, если вы рассматриваете Activity как часть представления, реализация MVC довольно проста. Вы можете переопределить Application (как возвращено getApplication () в Activity), и именно здесь вы можете создать контроллер, который выживет в течение всего времени жизни вашего приложения.

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

typingduck
источник
12

MVC - архитектура на Android Лучше следовать любому MVP, а не MVC в Android. Но все же согласно ответу на вопрос это может быть решение

Введите описание изображения здесь

Описание и рекомендации

     Controller -
        Activity can play the role.
        Use an application class to write the
        global methods and define, and avoid
        static variables in the controller label
    Model -
        Entity like - user, Product, and Customer class.
    View -
        XML layout files.
    ViewModel -
        Class with like CartItem and owner
        models with multiple class properties
    Service -
        DataService- All the tables which have logic
        to get the data to bind the models - UserTable,
        CustomerTable
        NetworkService - Service logic binds the
        logic with network call - Login Service
Helpers -
        StringHelper, ValidationHelper static
        methods for helping format and validation code.
SharedView - fragmets or shared views from the code
        can be separated here

AppConstant -
        Use the Values folder XML files
        for constant app level

ПРИМЕЧАНИЕ 1:

Теперь вот волшебство, которое вы можете сделать. Как только вы классифицируете часть кода, напишите базовый класс интерфейса, такой как, IEntity и IService. Объявите общие методы. Теперь создайте абстрактный класс BaseService и объявите свой собственный набор методов и разделите код.

ПРИМЕЧАНИЕ 2: Если ваша деятельность представляет несколько моделей, а не написание кода / логики в деятельности, лучше разделить представления на фрагменты. Тогда лучше. Поэтому в будущем, если для отображения в представлении потребуется еще какая-то модель, добавьте еще один фрагмент.

ПРИМЕЧАНИЕ 3: Разделение кода очень важно. Каждый компонент в архитектуре должен быть независимым, не иметь зависимой логики. Если случайно, если у вас есть что-то зависимая логика, то напишите класс логики отображения между ними. Это поможет вам в будущем.

DropAndTrap
источник
11

Создание пользовательского интерфейса Android с использованием макетов, ресурсов, действий и намерений является реализацией шаблона MVC. Пожалуйста, смотрите следующую ссылку для получения дополнительной информации об этом - http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

зеркало для PDF

Арунабх Дас
источник
7
связь прервана, сэр
Rat-a-tat-a-tat Ratatouille
2
Кажется, что этот файл COSC346-lab2.2up.pdf не содержит полную информацию.
Джеймс
9

Шаблон MVC в Android (вроде как) реализован с помощью их классов Adapter . Они заменяют контроллер на «адаптер». Описание для адаптера гласит:

Объект Adapter действует как мост между AdapterView и базовыми данными для этого представления.

Я просто смотрю на это для приложения Android, которое читает из базы данных, так что я пока не знаю, насколько хорошо это работает. Однако это похоже на архитектуру Model-View-Delegate в Qt, которая, как они утверждают, является шагом по сравнению с традиционным шаблоном MVC. По крайней мере, на ПК шаблон Qt работает довольно хорошо.

Бен
источник
9

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

android-binding - Предоставление структуры, которая позволяет связывать виджеты android view с моделью данных. Это помогает реализовать шаблоны MVC или MVVM в приложениях для Android.

roboguice - RoboGuice берет догадки из разработки. Введите свой View, Resource, System Service или любой другой объект, и пусть RoboGuice позаботится о деталях.

Махендра Лия
источник
9

Контроллер модельного представления (MVC)

введите описание изображения здесь


Описание:

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

Шаблон MVC по сути таков:

  • Модель: что отображать. Это может быть источник данных (например: сервер, необработанные данные в приложении)
  • Вид: как это отображается. Это может быть XML. Таким образом, он действует как фильтр представления. Представление присоединяется к его модели (или части модели) и получает данные, необходимые для презентации.
  • Контроллер: обработка событий, таких как пользовательский ввод. Это будет деятельность

Важная особенность MVC: мы можем модифицировать либо модель, либо вид, либо контроллер, по-прежнему не влияя на другие

  • Скажем, мы меняем цвет в представлении, размер представления или положение представления. Это не повлияет на модель или контроллер.
  • Скажем, мы изменим модель (вместо того, чтобы данные извлекались из сервера, извлекали данные из ресурсов), но это не повлияет на представление и контроллер
  • Скажем, мы меняем контроллер (логика в действии), это не повлияет на модель и представление
Devrath
источник
2
Я только когда-либо использовал контроллер в качестве канала для того, как просматривать / моделировать информацию о реле. Мне интересно, как у вас есть модель и вид в прямом контакте друг с другом. У вас есть источник или пример этой реализации?
Джексонкр
7

Я думаю, что наиболее полезное упрощенное объяснение здесь: http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

Из всего, что я видел и читал здесь, реализация всех этих вещей усложняет и не вписывается в другие части Android.

Осуществление действия, реализующего других слушателей, уже является стандартным способом Android. Самый безобидный способ - добавить Java Observer, как описывают слайды, и сгруппировать действия onClick и другие типы в функции, которые все еще находятся в Activity.

Способ Android заключается в том, что Activity делает и то, и другое. Борьба с ним на самом деле не делает расширение или создание будущего кода легче.

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

Эдмунд Чанг
источник
6
Указанная вами ссылка не работает.
mmBs
6

Было удивительно видеть, что ни один из постов здесь не ответил на вопрос. Они либо слишком общие, расплывчатые, неправильные или не относятся к реализации в Android.

В MVC слой View знает только, как отобразить пользовательский интерфейс (UI). Если для этого нужны какие-либо данные, они получают их со слоя модели . Но View НЕ напрямую просит модель найти данные, он делает это через Controller . Поэтому Контроллер  вызывает Модель для предоставления необходимых данных для Представления . Как только данные готовы, контроллер сообщает представлению, что данные готовы для получения из модели . Теперь представление может получать данные из модели .

Этот поток может быть кратко изложен ниже:

введите описание изображения здесь

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

Что касается реализации, одна из первых вещей, которая приходит на ум, это то, что какой компонент Android следует использовать для View ? Activity  или Fragment ?

Ответ в том, что это не имеет значения, и оба могут быть использованы. View должен быть в состоянии представить пользовательский интерфейс (UI) на устройстве и реагировать на взаимодействие пользователя с интерфейсом. И то, Activity  и другое Fragment  предоставляют необходимые методы для этого.

В примере приложения используется в этой статье я использовал Activity для View слоя, но Fragment  также могут быть использованы.

Полный пример приложения можно найти в ветке 'mvc' моего репозитория GitHub здесь .

Я также рассмотрел плюсы и минусы архитектуры MVC в Android на примере здесь .

Для тех , кто заинтересован, я начал серию статей о Android App архитектуре здесь , в которой я сравнить различные архитектуры, т.е. MVC, MVP, MVVM, для развития Android App через полное рабочее приложение.

Али Нем
источник
Я прошел курс архитектуры, где инструктор утверждает, что действия и фрагменты не должны использоваться в качестве представлений, а фактически должны быть контроллерами, а представления должны быть отдельными файлами. У вас есть мнение или аргументация, почему этого не должно быть?
brandonx
Я не думаю, что инструктор точен в этом. Выбор действия или фрагмента в качестве контроллера означает передачу контекста контроллеру. С другой стороны, представлению также нужен контекст для рисования на экране. Таким образом, т.е. передача контекста контроллеру, делает приложение подверженным утечке памяти, и я считаю, что контроллер не должен переносить состояние.
Али Нем
5

Устав от катастрофы MVx на Android, я недавно создал крошечную библиотеку, которая обеспечивает однонаправленный поток данных и похожа на концепцию MVC: https://github.com/zserge/anvil

По сути, у вас есть компонент (активность, фрагмент и группа просмотра). Внутри вы определяете структуру и стиль слоя представления. Также вы определяете, как данные должны быть связаны с представлениями. Наконец, вы можете связать слушателей в одном месте.

Затем, как только ваши данные будут изменены, будет вызван глобальный метод render (), и ваши представления будут обновлены с использованием самых последних данных.

Вот пример компонента, в котором есть все для компактности кода (конечно, модель и контроллер могут быть легко разделены). Здесь «count» - модель, метод view () - представление, а «v -> count ++» - контроллер, который прослушивает нажатия кнопок и обновляет модель.

public MyView extends RenderableView {
  public MyView(Context c) {
      super(c);
  }

  private int count = 0;

  public void view() {
    frameLayout(() -> {              // Define your view hierarchy
      size(FILL, WRAP);
      button(() -> {
          textColor(Color.RED);      // Define view style
          text("Clicked " + count);  // Bind data
          onClick(v -> count++);     // Bind listeners
      });
    });
  }

С разделенной моделью и контроллером это будет выглядеть так:

button(() -> {
   textColor(Color.RED);
   text("Clicked " + mModel.getClickCount());
   onClick(mController::onButtonClicked);
});

Здесь при каждом нажатии кнопки число будет увеличиваться, затем вызывается функция render () и текст кнопки будет обновляться.

Синтаксис становится более приятным, если вы используете Kotlin: http://zserge.com/blog/anvil-kotlin.html . Также существует альтернативный синтаксис для Java без лямбд.

Сама библиотека очень легкая, не имеет зависимостей, не использует отражения и т. Д.

(Отказ от ответственности: я автор этой библиотеки)

zserge
источник
4

Согласно объяснению, которое объяснила команда Xamarin (на iOS MVC «Я знаю, это кажется странным, но подожди секунду»):

  • Модель (логика данных или приложения),
  • Представление (пользовательский интерфейс) и
  • Контроллер (код сзади).

Я могу сказать это:

Модель на Android - это просто подлежащий продаже объект. Представление - это макет XML, а контроллер - (действие + его фрагмент).

* Это только мое мнение, а не из какого-либо ресурса или книги.

zaPlayer
источник
4

Не существует реализованной архитектуры MVC, но существует набор библиотек / примеров для реализации архитектуры MVP (модель-представление-презентатор).

Пожалуйста, проверьте эти ссылки:

Google добавил пример архитектуры Android MVP:

carlos.baez
источник
3

Я видел, что многие люди говорят, что MVC уже реализован в Android, но это не так. Android не следует MVC по умолчанию.

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

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

http://www.therealjoshua.com/2011/11/android-architecture-part-1-intro/

Но в настоящее время я думаю, что MVP вместе с Android Architectural Pattern является одним из лучших вариантов, который разработчики должны использовать для чистых и надежных приложений для Android.

Счастливая Рана
источник
1
Согласовано. У Android достаточно гибкости, чтобы повеситься. Ваша активность может быстро стать гигантской и сложной, поскольку она обрабатывает все три аспекта MVC.
Скотт Биггс
2

Когда мы применяем MVC, MVVM или Presentation Model к приложению для Android, мы действительно хотим иметь четко структурированный проект и, что еще важнее, его проще для модульных тестов.

На данный момент без сторонней среды у вас обычно есть много кода (например, addXXListener (), findViewById () и т. Д.), Который не добавляет никакой коммерческой ценности.

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

RoboBinding помогает вам писать код пользовательского интерфейса, который легче читать, тестировать и обслуживать. RoboBinding устраняет необходимость в ненужном коде, таком как addXXListener или около того , и переносит логику пользовательского интерфейса в Presentation Model, которая является POJO и может быть протестирована с помощью обычных тестов JUnit . Сам RoboBinding поставляется с более чем 300 тестами JUnit, чтобы гарантировать его качество.

Cheng
источник
1

В моем понимании, то, как Android обрабатывает шаблон MVC, выглядит следующим образом:

У вас есть активность, которая служит в качестве контроллера. У вас есть класс, который отвечает за получение данных - модель, а затем у вас есть класс View, который является представлением.

Говоря о представлении, большинство людей думают только о его визуальной части, определенной в XML. Давайте не будем забывать, что View также имеет программную часть со своими конструкторами, методами и т. Д., Определенными в классе java.

Rados
источник