Реализация шаблона MVC. Каково n-отношение между его компонентами

Я работаю над проектом C#, и мы, чтобы добиться некоторого единства в разных частях нашего пользовательского интерфейса, пытаемся использовать шаблон MVC. Клиент основан на форме Windows, и я пытаюсь создать простую реализацию шаблона MVC.

Это оказалось сложнее, чем ожидалось, но у меня все еще есть некоторые вопросы относительно шаблона MVC. Проблема возникает в основном из-за отношений n-n между его компонентами: вот что я понял, но я не уверен во всем этом. Может кто меня поправит?

  • Модель: может быть разделена между различными представлениями. 1-n связь между Model-View
  • Вид: показывает состояние модели. только один контроллер (может быть общим для разных представлений?). Связь 1-1 с Моделью, связь 1-1 с контроллером
  • Контроллер: обрабатывает действия пользователя в представлении и обновляет модель. Один контроллер может быть общим для разных представлений, контроллер взаимодействует только с одной моделью?

Я не уверен в двух последних:

  • Может ли представление иметь несколько контроллеров? Или представление может совместно использовать контроллер с другим представлением? Или это только отношения 1:1?
  • Может ли контроллер обрабатывать несколько представлений? может ли он взаимодействовать с несколькими моделями?

Кроме того, я воспользуюсь этим вопросом, чтобы задать другой вопрос, связанный с MVC. Я подавил все синхронные вызовы между различными членами MVC, используя события и делегаты. Последний вызов по-прежнему синхронен и на самом деле является самым важным: вызов между представлением и контроллером по-прежнему синхронен, так как мне нужно знать, смог ли контроллер обработать действие пользователя или нет. Это очень плохо, так как это означает, что я могу заблокировать поток пользовательского интерфейса (следовательно, сам клиент), пока контроллер обрабатывает или выполняет какую-то работу. Как я могу этого избежать? Я могу использовать обратный вызов, но как мне узнать, из какого события исходит обратный вызов?

PS: я не могу изменить шаблон на данном этапе, поэтому, пожалуйста, избегайте ответов типа «используйте MVP или MVVC и т. д.;)

Спасибо!


person srodriguez    schedule 08.03.2010    source источник


Ответы (3)


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

  • Контроллер возвращает один результат для одного действия; этот результат может быть реальным представлением или чем-то другим. Однако на самом деле контроллер никак не взаимодействует с представлением; все, что он делает, это предоставляет одну или две части информации в своем результате: имя представления, которое должно использоваться, и (необязательно) модель, используемая для заполнения. Механизм представления должен фактически создать и связать представление, что является значительным отклонением от обычной логики пользовательского интерфейса Smart Client.

  • Контроллер может взаимодействовать с несколькими различными частями Модели или вообще не взаимодействовать с ней в некоторых случаях; для этой стороны отношений нет правил. В результате действия контроллер должен вернуть либо 0, либо 1 экземпляр "модели", но это может быть не настоящая модель предметной области, а модель представления.

  • Представление обычно привязано ровно к одной модели (или модели представления), хотя в некоторых случаях представление может быть просто содержимым и, следовательно, ни к чему не привязано.

Итак, на очень грубом языке UMLesque:

  • Контроллер: Модель = 0..* : 0..*
  • Controller:View = 0..* : 0..1 (запрос) или 0..* : 0..* (всего)
  • Вид:Модель = 0..* : 0..1

Все это относится к ASP.NET MVC. Если бы вы разрабатывали свою собственную реализацию MVC, то, очевидно, вы могли бы реализовать ее так, как вам нравится. Однако удачи в реализации MVC в WinForms; Формы вообще не ведут себя как представления, даже такие шаблоны, как MVP/MVVM, довольно сложны (хотя и не невозможны, например CAB/SCSF от Microsoft), пока вы не перейдете на WPF.

person Aaronaught    schedule 08.03.2010
comment
Концептуальный слой — это очень хороший способ выразить это, и это была одна из идей, которые я пытался понять… - person kyoryu; 08.03.2010
comment
Трудно выбрать между тремя ответами, но твой ответ мне более понятен. Большое спасибо за разъяснения! - person srodriguez; 08.03.2010

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

**The Model**

Ваше описание довольно понятно, так что больше нечего сказать. Здесь я определяю свои бизнес-объекты. Я использую преимущества этого уровня для включения правил проверки объектов.

**The Controller**

Помимо обработки действий пользователя и обновления представления, у меня есть единица Работайте для каждого контроллера. Я проверяю, проходят ли объекты в представлении проверки (определенные на уровне модели) перед фиксацией изменений в единице работы.

В моем случае один контроллер может управлять многими моделями, и мне нравится иметь только одно представление в каждом контроллере.

Как предложение, я хотел бы использовать свою платформу с другим пользовательским интерфейсом, поэтому у меня есть абстрактная реализация контроллера, а затем у меня есть конкретные реализации контроллера для разных интерфейсов (WebForms, WinForms, ...).

**The Views**

В вашем случае мы могли бы назвать их просто формами, пользовательским интерфейсом и т. д. Мне нравится организовывать настольные приложения так, как если бы они были веб-приложениями, используя вкладки. Одна вкладка представляет один контроллер и т. д., одно представление и одну или несколько моделей.


В заключение и в моем случае:

n models - 1 controller
1 controller - 1 view
--
n models - 1 view
person Javier    schedule 08.03.2010

Вы, вероятно, слишком много думаете и слишком формализуете это.

Вот как я на это смотрю:

  1. Модель: Это реальная вещь, которая действительно работает.
  2. Контроллер: это то, что отправляет входные данные в модель, поэтому оно будет работать.
  3. Просмотр: здесь отображаются результаты.

Вот и все. Самая простая аналогия — это консольное приложение: приложение — это модель, STDIN — контроллер, а STDOUT — представление.

Продолжая эту аналогию, многие приложения с графическим интерфейсом создаются поверх приложений командной строки путем присоединения к STDIN/STDOUT. В этом случае элементы, отправляющие данные в STDIN, являются контроллером, элементы, принимающие данные из STDOUT и помещающие их в окно, — это представление, а консольное приложение по-прежнему является моделью.

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

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

Таким образом, должно ли 1 представление сопоставляться с 1 контроллером, или любые другие проблемы ортогональности являются второстепенными. На самом деле, вы, вероятно, должны просто делать то, что требует ваша проблемная область, но я бы (как обычно) возражал против чрезмерного обобщения кода - IOW, не смешивайте вещи, которые на самом деле то же самое.

person kyoryu    schedule 08.03.2010