Какова работа контроллера в MVC? - PullRequest
8 голосов
/ 17 января 2010

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

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

model.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);
?>

view.php

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

Я установил в браузере значение http://whateverhost/view.php?id=5

Это загружает пост с идентификатором 5. Мне не нужен контроллер здесь. Так что я запутался, зачем вам контроллер?

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

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

Ответы [ 6 ]

14 голосов
/ 17 января 2010

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

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

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

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

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

9 голосов
/ 27 июля 2016

IMO ...

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

Итак, в самом его основании:

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

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

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

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

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

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

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

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

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

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

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

Но подведем итог: контроллер «контролирует» операции и данные, поступающие в вашу систему и из нее, в и из представления, но на самом деле не делает бизнес . Детали этого процесса сильно зависят от философии вашего проекта.

MVC with N-Tier

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

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

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

2 голосов
/ 07 ноября 2013

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

Модель:

<?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>

CONTROLLER:

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

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

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

1 голос
/ 17 января 2010

model.php - это в этом случае вы контролируете.

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

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

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

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

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

0 голосов
/ 27 февраля 2017

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

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

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

0 голосов
/ 17 января 2010

ИМХО в MVC у контроллера есть два основных назначения :

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...