Должны ли представление и модель общаться или нет?


33

Согласно странице википедии по архитектуре MVC , представление может быть свободно уведомлено моделью, а также свободно запрашивать модель о ее текущем состоянии. Однако, согласно курсу Пола Хегарти по iOS 5 в Стэнфорде, лекция 1, стр. 18, все взаимодействие должно проходить через контроллер, с Model и View, которые никогда не должны знать друг друга. Мне не ясно, должно ли заявление Хегарти быть предназначено для упрощения курса, но я испытываю соблазн сказать, что он намеревается разработать проект как таковой.

Как вы объясните эти две противоположные точки зрения?

Ответы:


26

Это спорная тема в MVC / MVVM. Некоторые говорят, что это нормально для View, чтобы получить прямой доступ к Моделям, другие говорят, что вы должны обернуть Модели в ViewModels, чтобы абстрагировать их от View. Я лично не поклонник любого подхода.

Одной из основных целей MVC / MVVM является разделение пользовательского интерфейса, бизнес-логики и данных. Таким образом, учитывая эту концепцию, предоставление представлению прямого доступа к моделям создает зависимость, которую вы, возможно, не захотите иметь. С другой стороны, упаковка моделей в ViewModels часто является утомительной и не очень полезной, поскольку ViewModels, как правило, действуют просто как переход к моделям.

Мне нравится подход, при котором ваши модели реализуют определенный интерфейс, давайте назовем его IModel. Ваш класс ViewModel может затем предлагать экземпляры объектов, которые реализуют IModel для потребления View. View просто знает, что работает с объектами IModel, полученными из ViewModel. Это удаляет посторонний код оболочки ViewModel, а также скрывает конкретную реализацию IModel от View. Позже вы можете поменять одну реализацию IModel на другую, не влияя на просмотр одного бита.


1
Что касается утомительных аспектов отображения модели в модель представления, следует отметить, что существуют инструменты, которые могут облегчить боль при отображении. Например: (.NET AutoMapper) (JAVA modelmapper)
Джесси

+1 Отличный ответ! Это отличный подход в зависимости от сложности вашей модели, но большинство современных моделей относятся к типу Anemic . Элементы модели, представляющие собой нечто большее, чем объекты данных без поведения, практически не нуждаются в такой абстракции и не представляют особой опасности, позволяя вашему представлению напрямую обращаться к вашей модели.
maple_shaft

2
Я слышу, что вы говорите; большинство интерфейсов IModel просто содержат набор объявлений свойств и несколько (если таковые имеются) объявлений методов. Но даже если модели анемичны, интерфейс все равно отделяет представление от их конкретной реализации. Такое разделение может быть необязательным для каждого проекта, но всегда полезно держать свои параметры открытыми.
Рэймонд Салтрелли

1
Я в замешательстве, если у вас есть совершенно разные взгляды, как вы можете полагаться на интерфейс, не загромождая его? Я думаю, что View View являются фантастическими. Вы создаете Модели, которые достаточно универсальны для использования в вашем приложении, и вы создаете View View Models для использования одной или нескольких Моделей и дополнительно реализует операции, которые будут использоваться только этим представлением.
Человек

12

В Интернете каждый называет их разъединяющим MVC.

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

На чистом MVC View напрямую взаимодействует с моделью и наоборот. Контроллер доступен только при возникновении каких-либо изменений.

И затем, есть тот, который называется PAC (Контроль абстракции презентации). В этой архитектуре вид и модель не общаются друг с другом. Контроллер - единственный, кому разрешено делать что-либо с представлением или моделью. Люди часто путают это с MVC.

Вы найдете более подробное объяснение здесь: http://www.garfieldtech.com/blog/mvc-vs-pac


7

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

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


6

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

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

Затем есть MVVM, который похож на оба, но немного отличается и существовал давно ... лучше всего видеть его как два MVC / MVP, связанные вместе через объект viewmodel - у "клиентского" MVC есть viewmodel как его модель, и у "серверного" MVC есть модель представления как его представление.


1
Сегодня (в начале 2014 года) мне (с моим узлом и угловым стеком) это различие между MVC «клиент» и «сервер» MVC кажется очень актуальным и каким-то поучительным. (спасибо)
slacktracer

4

Поскольку вы спрашиваете о материале, в частности, в этих лекциях в Стэнфорде, стоит подумать о двух позициях Хегарти:

  1. Как вы упомянули, он преподает курс компьютерной науки уровня 100. В его лекциях есть много мест, где он упрощает, затушевывает детали или говорит «просто делай так», как это, вероятно, нужно при обучении основам, то есть ты должен освоить правила, прежде чем сможешь их нарушить.
  2. Мой опыт работы с iOS SDK заключается в том, что там, где он не обеспечивает строгого разделения между View и Model, он в значительной степени ориентирован на этот шаблон. При написании приложений для iOS, в частности, соблюдение разделения между моделями и представлениями помогает вам писать код, который соответствует ожиданиям платформы. Я бы не стал обобщать заявления Хегарти о разработке на других платформах или вообще.

1

Я согласен с Полом Хегарти и считаю, что мнение не должно знать о модели. Это не так сложно, но это приносит дополнительные преимущества вашему дизайну и будущей гибкости.

В небольших приложениях (обычно на настольных компьютерах), где я хотел бы избежать «фиктивных» классов ViewModel и сохранить простоту, я также использую интерфейс IModel (см. Ответ выше) и позаботился о том, чтобы Model не имела представления о представлении (используйте подписчиков) как в классическом MVC).

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

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


1

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

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

Помимо связи между моделями, в MVC есть еще одно противоречие с бизнес-логикой. Многие люди считают, что вся бизнес-логика должна быть одной моделью (см. Этот вопрос SO ), с другой стороны, ссылка, которую разделяет Флориан (в своем ответе), говорит, что бизнес-логика должна быть на контроллере.

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

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


0

Я использую DTO для связи модельного представления.

Например:

  • Пользователь заполняет форму обновления (Просмотр)
  • Пользователь отправляет форму
  • Контроллер привязывает данные формы к UserUpdateDTO
    • DTO и UserModel являются POJO, но у DTO нет идентификатора и имени пользователя, потому что мы не можем обновить имя пользователя.
    • Другое отличие состоит в том, что класс Model имеет отношения и ассоциации, но DTO хранит только данные, и мы можем добавить в него валидаторы JSR 303
  • Контроллеры говорят это сервисному слою, чтобы сохранить
  • Уровень обслуживания сообщает уровню DAO для сохранения данных

-1

Я из лагеря, который говорит, что представление никогда не должно общаться с моделью. Контроллер всегда должен быть постоянным помощником во всем, затем он решает, что делать (проверять, запрашивать данные из модели и т. Д.).

Я склонен рассматривать это скорее как организационную проблему, чем что-либо еще.


-1

Многие предлагают, почему и как представления и модели должны свободно взаимодействовать в разных контекстах, но главная причина, по которой iOS создает Controller, заключается в том, что посредником между ними является избегание зависимостей Model & View в вашей кодовой базе и возможность повторного использования. либо модель или вид в соответствии с требованиями с развитием iOS.

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

Хотя я согласен с тем, что MVC в iOS производит гигантские контроллеры ViewController с множеством различных логик, которые обрабатывают все, кроме того, для чего он предназначен. Поэтому лучше использовать MVVM или элементы управления презентациями, чтобы сделать вашу кодовую базу более гибкой, легкой читать и поддерживать с меньшими ViewControllers.

Это может помочь тем, кто ищет меньшие ViewControllers в iOS:

http://blog.xebia.com/simplification-of-ios-view-controllers-mvvm-or-presentation-controls/

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.