Что входит в " контроллер "в"MVC"?


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

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

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

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

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

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

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

13 165

13 ответов:

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

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

посмотреть: "Эй, контроллер, пользователь только что сказал мне, что он хочет пункт 4 удаленный."
контроллер: Хм, проверив его полномочия, он может это сделать... Эй, модель, я хочу, чтобы ты взяла пункт 4 и сделала все, чтобы удалить его."
модель: "пункт 4... понял. Он удален. Вернемся к вам, контролер."
контроллер: "вот, я соберу новый набор данных. Вернемся к тебе, вид."
посмотреть: "круто, я покажу новый набор к пользователя."

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

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

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

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

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

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

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

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

... любые проверки и т. п. сделано в контроллере? Если да, то как это сделать I сообщения об ошибках обратной связи обратно в Посмотреть-должно ли это пройти Модель снова, или должен контроллер просто отправить его обратно на просмотр?

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

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

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

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

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

здесь хорошая статья Об основах MVC.

его государства ...

контроллер-контроллер переводит взаимодействие с представлением в действия, которые будут выполняться моделью.

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

есть еще один хороший статья в Fowler.

шаблон MVC просто хочет, чтобы вы отдельной презентации (=view) из логики бизнеса (= модель). Часть контроллера существует только для того, чтобы вызвать путаницу.

основываясь на вашем вопросе, у меня создается впечатление, что вы немного туманны в роли модели. Модель фиксируется на данных, связанных с приложением; если приложение имеет базу данных, задача модели будет говорить с ним. Он также будет обрабатывать любую простую логику, связанную с этими данными; если у вас есть правило, которое говорит, что для всех случаев, когда таблица.фу = = " Ура!- и стол.бар = = " Ура!- тогда накрывай на стол.поле="W00t!", тогда вы хотите, чтобы модель позаботилась оно.

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

" помещаю ли я public void actionPerformed (ActionEvent e) в представление только с вызовом метода в контроллере?"

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

" Если да, то следует ли выполнять проверку и т. д. В контроллере?"

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

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

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

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

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

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

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

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

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

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

сервис-ориентированный: вот где делается работа.

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

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

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

public void actionPerformed(ActionEvent e)

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

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

Я определенно рекомендовал бы взглянуть на пассивное представление и наблюдение за Презентатором (который по существу является тем, на что разделен Model View Presenter - по крайней мере, Фаулером). Смотрите:

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

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

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

Я придумал это после работы с большим веб-приложением, написанным разработчиками, которые думали, что они понимают MVC, но на самом деле этого не сделали. их "контроллеры" сводятся к восьми строкам вызова статические методы класса, которые обычно нигде не называются: - / создание их моделей немного больше, чем способы создания пространств имен. Рефакторинг это правильно делает три вещи: сдвигает весь SQL на уровень доступа к данным (aka model), делает код контроллера немного более подробным, но намного более понятным и сводит старые файлы "модели" к нулю. : -)

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

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

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

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

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

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

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

->main ()

->handleSubmit_AddNewCustomer ()

->verifyUser_HasProperAuth ()

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

->sanityCheck_AddNewCustomer ()

->handleUsernameChange()

- >sendEmail_NotifyRequestedUpdate ()

(3) (просмотры, порталы, как появляется веб-приложение") Blog_View

->genWelcome()

->genForm_AddNewBlogEntry ()

->genPage_DataEntryForm ()

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

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

->saveDataToMemcache()

->saveDataToMongo()

->saveDataToSql()

->loadData ()

иногда мы немного путаемся в том, где поместить метод, в C или L. Но модель является твердой, кристально чистой, и поскольку все данные в памяти находятся в _Meta, там тоже нет проблем. Наш самый большой скачок форвард принимал использование _Meta, кстати, поскольку это очистило всю грязь от различных объектов _C, _L и _Model, сделало все это умственно легким в управлении, плюс, одним махом, это дало нам то, что называется "инъекцией зависимости", или способ передать всю среду вместе со всеми данными (чей бонус-легкое создание "тестовой" среды).