Вопрос по java – Что входит в «Контроллер» в «MVC»?

173

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

Допустим, например, что у меня довольно простое приложение (я специально думаю о Java, но я полагаю, что те же принципы применимы и в других местах). Я организую свой код в 3 пакетаapp.model, app.view а такжеapp.controller.

В пределахapp.model пакет, у меня есть несколько классов, которые отражают реальное поведение приложения. Этиextends Observable и использоватьsetChanged() а такжеnotifyObservers() для запуска просмотра обновлять при необходимости.

app.view Пакет имеет класс (или несколько классов для разных типов отображения), который используетjavax.swing компоненты для обработки дисплея. Некоторые из этих компонентов должны быть возвращены в модель. Если я правильно понимаю, View не должен иметь ничего общего с обратной связью - с этим должен справиться Контроллер.

Так, что я фактически помещаю в Контроллер? Я положилpublic void actionPerformed(ActionEvent e) в представлении с просто вызовом метода в контроллере? Если да, следует ли выполнять какие-либо проверки и т. Д. В контроллере? Если да, то как я могу отправить сообщения об ошибках обратно в View - это должно пройти через Модель снова, или Контроллер должен просто отправить его обратно в View?

Если проверка выполняется в представлении, что я помещаю в контроллер?

Извините за длинный вопрос, я просто хотел документировать свое понимание процесса, и, надеюсь, кто-то может прояснить этот вопрос для меня!

Ваш Ответ

13   ответов
1

что каждый виджет Swing может рассматриваться как содержащий три компонента MVC: каждый имеет Model (т.е. ButtonModel), View (BasicButtonUI) и Control (сам JButton).

3

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

Я пришел к этому после работы с веб-приложением большого размера, написанным разработчиками, которые думали, что они понимают MVC, но на самом деле это не так. Их & quot; контроллеры & quot; сокращены до восьми строк вызова методов статического класса, которые обычно нигде не вызваны: - / делая их модели немного больше, чем способы создания пространств имен. Правильный рефакторинг делает три вещи: переводит весь SQL на уровень доступа к данным (он же модель), делает код контроллера более многословным, но гораздо более понятным и уменьшает старую «модель». файлы ни к чему. :-)

9

у меня сложилось впечатление, что вы немного помутнели над ролью Модели. Модель фиксируется на данных, связанных с приложением; если приложение имеет базу данных, работа модели будет состоять в том, чтобы общаться с ней. Он также будет обрабатывать любую простую логику, связанную с этими данными; если у вас есть правило, которое гласит, что для всех случаев, когда TABLE.foo == & quot; Ура! & quot; и TABLE.bar == & quot; Huzzah! & quot; затем установите TABLE.field = & quot; W00t! & quot ;, затем вы хотите, чтобы модель позаботилась об этом.

Контроллер - это то, что должно обрабатывать основную часть поведения приложения. Итак, чтобы ответить на ваши вопросы:

& quot; Помещаем ли я открытый void actionPerformed (ActionEvent e) в View только с помощью вызова метода в Controller? & quot;

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

& quot; Если да, следует ли выполнять какую-либо проверку и т. д. в контроллере? & quot;

Большая часть вашей проверки действительно должна быть сделана Контроллером; он должен ответить на вопрос о том, являются ли данные действительными или нет, и направить соответствующие сообщения об ошибках в представление. На практике вы можете включить несколько простых проверок работоспособности в слой View для улучшения взаимодействия с пользователем. (Я имею в виду, прежде всего, веб-среды, в которых может потребоваться всплывающее сообщение об ошибке в тот момент, когда пользователь нажимает кнопку «Отправить», а не ждать весь цикл отправки -> процесс -> загрузки страницы, прежде чем сообщить им они облажались.) Просто будьте осторожны; Вы не хотите дублировать усилия больше, чем должны, и во многих средах (опять же, я думаю о сети) вам часто приходится обрабатывать любые данные, поступающие из пользовательского интерфейса, как пачку грязной грязи. ложь, пока вы не подтвердите, что это действительно законно.

& quot; Если да, то как мне отправить сообщения об ошибках обратно в представление - должно ли это снова пройти через модель или контроллер просто отправит ее обратно в просмотр? & quot;

У вас должен быть установлен некоторый протокол, в котором представление не обязательно знает, что будет дальше, пока контроллер не сообщит об этом. Какой экран вы показываете после того, как пользователь нажимает эту кнопку? Представление может не знать, и контроллер может не знать, пока он не просмотрит данные, которые он только что получил. Это может быть "Перейти к этому другому экрану, как и ожидалось" или "Оставайтесь на этом экране и отображайте это сообщение об ошибке".

По моему опыту, прямое взаимодействие между Моделью и Представлением должно быть очень, очень ограниченным, и Представление не должно напрямую изменять какие-либо данные Модели; это должно быть работой Контролера.

& quot; Если проверка выполняется в представлении, что я могу добавить в контроллер? & quot;

Смотри выше; реальная проверка должна быть в контроллере. И, надеюсь, у вас есть некоторое представление о том, что уже нужно поместить в контроллер. :-)

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

0

используя контроллеры в основном для обработки и реагирования на пользовательский ввод / действия (и _Logic для всего остального, кроме представления, данных и очевидных вещей _Model):

(1) (ответ, реакция - то, что веб-приложение "делает" в ответ пользователю) Blog_Controller

- & GT; основные ()

- & GT; handleSubmit_AddNewCustomer ()

- & GT; verifyUser_HasProperAuth ()

(2) («бизнес-логика», что и как думает веб-приложение ») Blog_Logic

- & GT; sanityCheck_AddNewCustomer ()

- & GT; handleUsernameChange ()

- & GT; sendEmail_NotifyRequestedUpdate ()

(3) (просмотры, порталы, как выглядит веб-приложение & quot;) Blog_View

- & GT; genWelcome ()

- & GT; genForm_AddNewBlogEntry ()

- & GT; genPage_DataEntryForm ()

(4) (только объект данных, полученный в _construct() of each Blog* класс, используемый для хранения всех данных веб-приложения / памяти как одного объекта) Blog_Meta

(5) (базовый уровень данных, чтение / запись в БД) Blog_Model

- & GT; saveDataToMemcache ()

- & GT; saveDataToMongo ()

- & GT; saveDataToSql ()

- & GT; LoadData ()

Иногда мы немного запутываемся в том, куда поместить метод, в C или L. Но Модель очень прочная, кристально чистая, и, поскольку все данные в памяти находятся в _Meta, там нет ничего сложного, тоже. Между прочим, нашим самым большим шагом вперед было принятие использования _Meta, поскольку это очистило весь сырой от различных объектов _C, _L и _Model, сделало его умственно простым для управления, плюс, одним махом, это дало нам то, что & apos; Это называется «Внедрение зависимостей» или способ обойти всю среду вместе со всеми данными (преимуществом является простое создание «тестовой» среды).

1

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

В любом случае, правильная реализация MVC будет иметь только следующие взаимодействия: Модель - & gt; Посмотреть Вид - & gt; контроллер Контроллер - & gt; Посмотреть

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

7

Контроллер действительно является частью View. Его задача - выяснить, какие службы необходимы для выполнения запроса, разархивировать значения из представления в объекты, необходимые для интерфейса службы, определить следующее представление и преобразовать ответ обратно в форму, которую может использовать следующее представление. , Он также обрабатывает любые возникающие исключения и отображает их в представления, понятные пользователям.

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

Сервис-ориентированный: здесь работа выполнена.

23

хорошая статья по основам MVC.

Говорится ...

Controller - The controller translates interactions with the view into actions to be performed by the model.

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

Есть еще один хорошийстатья в Фаулер.

Error: User Rate Limit Exceeded Paul Walker
Error: User Rate Limit Exceededmartinfowler.com/eaaDev/ModelViewPresenter.html
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
471

"пользователь нажал кнопку" удалить этот элемент "; Кнопка & Quot; в интерфейсе в основном следует просто вызывать контроллер «удалить» функция. Контроллер, однако, не имеет представления о том, как выглядит представление, и поэтому ваше представление должно собирать некоторую информацию, например, «какой элемент был нажат»?

В форме разговора:

View: "Эй, контроллер, пользователь только что сказал мне, что хочет удалить элемент 4."
Controller: "Хм, проверив свои учетные данные, ему разрешено сделать это ... Эй, модель, я хочу, чтобы ты получил элемент 4 и сделал все, что ты делаешь, чтобы удалить его."
Model: "Пункт 4 ... получил. Он удален. Назад к вам, Контролер. & Quot;
ControllerЗдесь я собираю новый набор данных. Вернуться к вам, просмотр. & Quot;
View: "Классно, я сейчас покажу новый набор пользователю".

В конце этого раздела у вас есть опция: либо представление может сделать отдельный запрос, "дать мне самый последний набор данных" и, таким образом, быть более чистым, либо контроллер неявно возвращает новый набор данных с помощью & quot ; удаление & Quot; операция.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Paul Walker
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededreadingError: User Rate Limit Exceededrmauger.co.uk/2009/03/…
0

Контроллер переводит из действий пользовательского интерфейса в действия на уровне приложений. Например, в видеоигре контроллер может перевести «сдвинул мышь на столько пикселей» в "хочет смотреть в том-то и таком-то направлении. В приложении CRUD перевод может быть «нажат на такой-то кнопке»; «напечатать эту вещь», но концепция та же.

3

ием и моделью.

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

Я предлагаю вам поставить:

public void actionPerformed(ActionEvent e)

в контроллере. Тогда ваш слушатель действия, по вашему мнению, должен делегировать контроллеру.

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

Я бы определенно рекомендовал взглянуть на Passive View и Supervising Presenter (по сути, именно на это разделен Model View Presenter - по крайней мере, Фаулер). Увидеть:

http://www.martinfowler.com/eaaDev/PassiveScreen.html

http://www.martinfowler.com/eaaDev/SupervisingPresenter.html

60

MVC в том, что люди думают, что представление, контроллер и модель должны быть максимально независимыми друг от друга. Они не - видение и контролер часто переплетаются - считают этоM(VC).

Контроллер является механизмом ввода пользовательского интерфейса, который часто запутывается в представлении, особенно в графических интерфейсах. Тем не менее, представление выводится, а контроллер - вводится. Представление часто может работать без соответствующего контроллера, но контроллер обычно гораздо менее полезен без представления. Удобные для пользователя контроллеры используют представление для интерпретации ввода пользователя более осмысленным и интуитивно понятным способом. Это то, что затрудняет отделение концепции контроллера от представления.

Представьте себе в качестве модели радиоуправляемого робота на поле обнаружения в запечатанном ящике.

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

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

Подумайте о контроллере без представления, например кто-то заперт в шкафу с радиоконтроллером, настроенным на частоту робота. Этот контроллер отправляет входные данные и вызывает переходы состояний, не имея представления о том, что они делают с моделью (если что-либо). Легко представить, но не очень полезно без какой-либо обратной связи с точки зрения.

Наиболее удобный пользовательский интерфейс координирует представление с контроллером, чтобы обеспечить более интуитивно понятный пользовательский интерфейс. Например, представьте вид / контроллер с сенсорным экраном, показывающий текущее положение робота в 2-D и позволяющий пользователю касаться точки на экране, которая, как оказалось, находится перед роботом. Контроллеру нужны подробности о представлении, например, положение и масштаб области просмотра, а также положение точки, которой коснулись пикселя относительно положения пикселя робота на экране), чтобы правильно интерпретировать это (в отличие от парня, запертого в шкафу с радиоконтроллером).

Я уже ответил на ваш вопрос? :-)

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

... should any validation etc be done in the Controller? If so, how do I feedback error messages back to the View - should that go through the Model again, or should the Controller just send it straight back to View?

If the validation is done in the View, what do I put in the Controller?

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

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

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

Если другие взглядыdo необходимо знать об этих ошибках, то вы фактически говорите, что входные данные от пользователя и любые возникающие ошибкиpart of the model и все это немного сложнее ...

15

separate the presentation (= просмотр)from the buisiness logic (= модель). Контроллер часть только для того, чтобы вызвать путаницу.

Error: User Rate Limit Exceeded
9

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

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

Похожие вопросы