Какова работа контроллера в MVC?

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

модель.php подключается к базе данных и получает сообщение. вид.php просто отобразит сообщение.

модель.в PHP

<?php
  $db = mysql_connect("somehostname", "someuser", constant("somepassword"));
  mysql_select_db("somedatabase", $db);

  $result = mysql_query("SELECT post FROM posts WHERE postid='" . $_POST['id'] . "'");
  $row = mysql_fetch_array($result);

  $post = $row["post"];

  mysql_close($db);
?>

вид.в PHP

<?php
  require "model.php";
  echo $post;
?>

Я установил местоположение браузера в http://whateverhost/view.РНР?id=5

это загружает сообщение с идентификатором 5. Я не требуется контроллер здесь. Поэтому я смущен, зачем вам нужен контроллер?

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

Edit: было бы здорово, если бы вы могли добавить контроллер.php к вышеуказанному коду. Это помогло бы мне понять роль контроллера и то, как он взаимодействует с моделью и представлениями.

6 ответов


вам не нужен контроллер, потому что ваш пример является тривиальным. Пример из реального сценария:

Предположим, у вас есть приложение CAD. Применение CAD аранжировано как MVC. У вас есть:

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

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

конечно, вы могли бы сказать, почему представление не создает объекты команды? ну, никто тебе этого не запрещает, но в итоге логика презентации смешается с логикой работы. Это противоречит хорошему дизайну, хотя в самых тривиальных случаях вы можете жить с этим дизайном. Например, если приложение САПР позволяет отображать список объектов как в виде 3D-представления, так и в виде списка объектов, и вы можете удалить их из обоих, вы ясно видите что либо оба представления реализуют одну и ту же логику для обработки шаблона команды (плохой дизайн), либо они просто направляют одно и то же сообщение на общий контроллер (хороший дизайн, MVC).


ИМО...

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

поэтому в его база:

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

View: это то, что пользователь видит и как пользователь взаимодействует. Любой код или логика здесь должны непосредственно поддерживать представление. Другими словами, нулевая бизнес-логика, нулевая логика доступа к данным, нулевое знание чего-либо за пределами того, что пользователь физически видит. Веб-форма, окно рабочего стола форма, или активности (мобильные) и т. д...

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

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

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

Если вы можете принять это утверждение, то оно должно помочь прояснить, что модель действительно в этом контексте. Модель не является объектом доступа к данным, и модель не является моделью домена, потому что ни одна из этих вещей не должна находиться на уровне презентации. Так что остаемся мы. с помощью ViewModel (MVVM) или DTO. Я собираюсь пойти с DTO ради простоты.

Итак, если мы приняли DTO как тип модели, о которой мы говорим, когда говорим "модель" в MVC, то где мы ее получаем? Если контроллер не должен возиться с доступом к данным, то где? Как насчет уровня обслуживания? Ваш уровень обслуживания содержит все " как " вашего приложения. Это слой "делать вещи". Поэтому, если ваше представление хочет создать пользователя, оно будет собирать данные и передай это контроллеру. Контроллер решает, какую службу(ы) вызвать для выполнения задачи и отправляет ей запрос с необходимыми данными. Уровень обслуживания отвечает DTO. Этот DTO можно использовать напрямую или добавить в другую модель (например, если было вызвано несколько служб).

важными моментами являются:

  • контроллер ничего не знает о вашем домене (если он у вас есть), он знает только о наличии услуги и как их называть.
  • абсолютно нет бизнес логика выполняется контроллером. Например, если вам нужно отправить приветственное письмо как часть операции CreateUser, это не будет инициировано контроллером, так как это технически бизнес-правило. Он будет обрабатываться между вашим сервисом и доменными слоями.
  • на мой взгляд, никакой доступ к данным не должен выполняться вашим контроллером. Это должно быть делегировано службе слой. Многие учебники, как правило, показывают контроллер, взаимодействующий с репозиториями, что, я думаю, хорошо, потому что это абстракция, но прямой доступ к данным должен быть абсолютным нет нигде в слое презентации.

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

Так в MVC.Net, контроллер больше похож на API; представление и API-это два разных носителя представления, которые предназначены для совместной работы (бэкэнд-контроллер представляет данные, фронтенд-контроллер строит модели с этими данными и опосредует представление). В Angular контроллер больше похож на то, о чем мы здесь говорим. Кажется, слои слоев слоев. Это немного запутанно, чтобы концептуализировать, но концепция никогда не выходит за пределы уровня представления.

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

MVC with N-Tier

Итак, здесь, на этой диаграмме, я сгруппировал понятия, чтобы показать MVC внутри N-уровня в типичном монолитное применение. Коммуникация выполняется слева направо и не перепрыгивает через какой-либо другой слой (см.: архитектура Onion). На уровне представления контроллер знает о модели и представлении, но представление и модель по большей части ничего не знают. Однако во многих вкусах MVC, в том числе ASP.Net и MVVM, представление может знать о модели интерфейс или прототип (но не экземпляр модели), чтобы он мог привязываться к нему.

в контроллер будет обрабатывать манипуляции с моделью (или моделью представления в этом контексте), что означает, что ему может потребоваться знать об объекте домена и доменных службах. При необходимости можно вставить слой приложения между слоем презентации и доменом, если требуется более многоразовое приложение (например, приложение может иметь несколько головок: веб-API, настольное приложение, мобильное приложение и т. д.).) обеспечить транзакционную границу и дальнейшую изоляцию. Важно, что вид имеет нет знаний / зависимости от объектов домена в этой архитектуре - вот почему существует отдельная модель для представления. Смысл модели в MVC заключается в создании модели для просмотра. То есть это модель, специально разработанная для обслуживания представления, а не домена. Модель представления может обернуть / адаптировать модель домена, если она никогда не выставляется публично и / или случайно сериализована.

на боковой ноте, "уровень презентации" в веб-API, на мой взгляд, является сериализованным контрактом (например, JSON или XML). Поэтому относитесь к этому соответственно.


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

модель:

<?php
  $db = mysql_connect("somehostname", "someuser", constant("somepassword"));
  mysql_select_db("somedatabase", $db);

  $result = mysql_query("SELECT post FROM posts WHERE postid='" . $_POST['id'] . "'");
  $row = mysql_fetch_array($result);

  $post = $row["post"];

  mysql_close($db);

function getPost() {
    return $post;
}
?>

вид:

<html>
<head></head>
<body>
    <input type="submit" onClick="postToScreen();" value="Post">
    <p id="post"></p>
</body>
</html>

:

<?php
    $controllerPost = getPost();
?>

<script type="text/javascript">
function postToScreen() {
    document.getElementById("post").innerHTML="<?php echo $controllerPost; ?>";
}
</script>

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


модель.в PHP is в этом случае вас контроллер.

роли модели, представления и контроллера нелегко отличить, если у вас нет хорошей структуры MVC (простой PHP не является хорошим).

модель-это ваша структура данных, которая является постоянной в БД. С точки зрения кода, если, в основном, состоит из структуры данных, как класс.

представление просто отображает данные. В основном html с некоторыми тегами сценариев.

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

просто небольшой пример.


ИМХО в MVC контроллер имеет две основные цели:

  1. на контролепригодность логики GUI или что-нибудь, что запускает GUI. В большинстве случаев вы можете написать модульные тесты для контроллера относительно легко, это намного сложнее для GUIs, таких как PHP или Windows Forms, например. Первый зависит от браузера, а позже зависит от сообщений Windows, оба не делает вашу жизнь проще, когда вы пишете модульные тесты. Это почти то же самое с любым другим технология презентационного слоя.
  2. на учетом взаимозаменяемости между уровня представления или (в некоторых случаях) контроллера. Существуют сценарии, в которых вы можете использовать один и тот же контроллер в двух GUIs ("легкая" форма для специального случая и "богатая" форма для другого случая) или наоборот (не так часто).

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


Я постараюсь ответить только на вопрос в названии. Итак, какова роль контроллера в MVC?

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

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