MVC для начинающих

и для интернета в частности

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

Впервые услышав такие слова, как Model View Controller, мне было интересно, но немного не ясно, поскольку, не зная ничего о шаблонах проектирования, разобраться в конкретном их случае, достаточно сложно. Мешало малое количество опыта в разработке приложений, да и вообще малая осведомлённость в подобном вопросе.

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

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

Стандартная схема архитектуры «Модель-Вид-Контроллер» изображена на следующем рисунке: (схема заимствована из книги «Ajax in action» издательского дома «Вильямс»)

Схема архитектуры MVC Схема архитектуры MVC

Разберём по пунктам данную схему.

В шаблоне MVC, как следует из названия, есть три основных компонента: Модель, Представление, и Контроллер.

Представление (вид) отвечает за отображение информации, поступающей из системы или в систему.

Модель является «сутью» системы и отвечает за непосредственные алгоритмы, расчёты и тому подобное внутреннее устройство системы.

Контроллер является связующим звеном между «представлением» и «моделью» системы, посредством которого и существует возможность произвести разделение между ними. Контроллер получает данные от пользователя и передаёт их в «модель». Кроме того, он получает сообщения от модели, и передаёт их в «представление».

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

Итак, условимся:

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

Контроллер. Модуль управления вводом и выводом данных. Данный модуль должен следить за переданными в систему данными (через форму, строку запроса, cookie или любым другим способом) и на основе введённых данных решить:

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

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

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

Но на самом деле ничего сверхсложного в этом нет.

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

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

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

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

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

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

Диаграмма последовательностей Диаграмма последовательностей

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

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

Диаграмма классов Диаграмма классов

Диаграмма классов содержит три класса, по одному для каждого компонента архитектуры MVC. Для удобства, они так и названы: Model, View, Controller.

В представлении есть три функции (хотя, вполне возможно обойтись только лишь одной), которые отвечают за отображение состояния приложения:
displayDefault() – вывод формы по умолчанию.
displayError(error = false) – вывод формы с сообщением об ошибке, либо отдельной формы с ошибкой
displayResults() – вывод результатов вычислений

Контроллер имеет не только методы, но и поля. С полями всё просто: это ошибка и результаты вычислений. По умолчанию им задаётся значение false, что свидетельствует о том, что пока нет ни ошибки, ни результатов.

Три метода, присутствующие в контроллере, служат для управления и проверки. Метод для проверки (validate()) является необязательным, и вполне может отсутствовать, если никаких проверок не требуется.

Метод processData() служит для вывода формы по умолчанию, однако он включает также метод userRequest(), функциональность которого выполняется лишь в том случае, когда есть введённые пользователем данные. Именно метод userRequest() содержит в себе функцию validate() (если данные не введены, следовательно, незачем делать их проверку) и, кроме того, должен содержать вызов конструктора класса модели.

В модели может содержаться любое количество полей и методов. Однако два метода должны быть обязательными (или даже один. Как удобнее будет).
calculate() – функция, производящая основной расчёт
getData() – функция, возвращающая данные результата.

Разделение функций модели скорее смысловое. Вполне достаточно создать один метод, который будет и считать, и возвращать результат.

Возвращаемся в метод userRequest() контроллера. После того, как в нём был посчитан результат и возвращён в том или ином виде, его можно смело отдавать на вход функции displayResults() класса View. Однако заметим, что в принципе, можно отдавать на вход представления и экземпляр класса модели, если вывод оного хранится в его полях, а их много (если лень, так сказать, создавать структуру, массив либо ещё какой-либо объёмный тип данных).

Если функция validate() контроллера выявила ошибку, и установила значение поля error в значение, отличное от false, контроллер сам вызовет метод displayError() класса View.

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

Диаграмма последовательностей Диаграмма последовательностей

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

Например, в представлении мы можем написать:

	// Это код на PHP
	public function displayDefault() {
	
		echo "<p>Введите имя:  ";
		echo "<input type='text' name='name' value=''>  ";
	
	}

А потом через месяц ужаснуться, и перейти к использованию шаблонизатора. Скажем, smarty.

Или, например, в модели изменить пару расчетных формул. Или в контроллере убрать пару ограничений, или изменить метод приёма-передачи данных. Если же взять в расчёт принципы наследования в ООП, то архитектура MVC станет ещё удобнее. Скажем, когда есть две формы, выглядящие одинаково, но с несколько отличающимися алгоритмами расчёта.

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

<?

/**
*	Пример реализации MVC на PHP
*
**/

class Controller {

private $error;
private $result;

	function __construct() {
	
		$this->error = false;
		$this->result = false;
	
	}



	function processData() {
	
		$this->userRequest();
		
		if ($this->error)
			View::displayError($this->error);
		else
		if ($this->result)
			View::displayResults($this->result);
		else
			View::displayDefault();
	
	}
	
	function userRequest() {
	
		// данные отправлены
		if (isset($_POST['send'])) {
	
			$this->validate();
			
			if (!$this->error) {
			
				// основные вычисления
				$model = new Model();
				$model->calculate($_POST['name']);
				$result = $model->getData();
				
				// проверка на ошибки в самой модели
				if (!is_array($result))
					$this->error = $result;
					
				else
					$this->result = $result;
			
			}
		}
	}
	
	function validate() {
	
		if (empty($_POST['name']))
			$this->error = 'Не введено имя!';
		else	
		if (strlen(strval($_POST['name'])) < 3)
			$this->error = 'Имя слишком короткое!';
	
	}

} // class Controller


class View {

	static function displayDefault() {
	
		echo "<form method='POST' action=''>";
		echo "<p>Введите имя:  ";
		echo "<input type='text' name='name' value=''>  ";
		echo "<input type='submit' name='send' value='Отправить'>";
		echo "</form>";
	
	}
	
	static function displayError($error) {
	
		echo "<p><b>Ошибка:</b> {$error}";
		View::displayDefault();
	}
	
	static function displayResults($results) {
	
		echo "<p><b>Результаты:</b>";
		echo "<p>Ваше имя <b>".$results[0].
			"</b> означает <i>".$results[1]."</i>";
		echo "<p><a href='".$_SERVER['REQUEST_URI'].
					"'>Узнать ещё об одном имени</a>";
	}	

} // class View


class Model {

private $data;

	function __construct() {
	
		$this->data = false;
	
	}

	function calculate($name) {
	
		$this->data[] = $name;
	
		$len = strlen($name);
	
		if ($len == 3) 
			$this->data[] = 'краткость - сестра таланта';
		else
		if (($len > 3) && ($len < 6))
			$this->data[] = '...нет особого значения';
		else
			$this->data[] = 'невероятно богатая фантазия родителей';
	}

	function getData() {
	
		if ($this->data) 
			return $this->data;
		else
			return 'Вычисления не произведены!';
	
	}

} // class Model


$controller = new Controller();

$controller->processData();

?>

Работу данного кода можно увидеть в примере.

Итак, мы получили простейшую MVC-систему. Выделим положительные и отрицательные стороны:

К минусам можно отнести

Последнее требование к нашему примеру не относится, но для реальных систем оно весьма актуально.

К плюсам отнесём следующее:

Надо сказать, что код примера не идеален. В нём есть просторы для рефакторинга (несмотря на то, что он занимает чуть более ста строк). Скажем, в примере участвует всего лишь одна переменная, поступающая от пользователя (name), но что если их будет много? Как их хранить? Как сделать так, чтобы при изменении метода, не пришлось править код более чем в одном месте?

Всё это оставьте себе в качестве домашнего задания.

Разбор несколько более сложного примера, можно посмотреть в статье «Рейтинг с помощью MVC».

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

P.S. Отметим, что класс контроллера вдобавок построен по архитектурному шаблону Facade, суть которого состоит в сокрытии внутреннего устройства системы и предоставлении пользователю только функций самого высшего уровня. Эту суть убедительно доказывают две последние строки кода.



UPD0: На самом деле шаблон MVC куда более общий, мы рассмотрели, скорее, его вариант в виде MVP - Model View Presenter, где контроллер есть "медиатор" между представлением и моделью. Более того, в случае реализации MVC в GUI приложениях используют не так называемый Flow-подход (контроллер сам обращается к модели и представлению), а событийный подход с использованием шаблона Observer.


UPD1: Фреймворк CakePHP использует шаблон MVC, запрос к фреймворку изображён на этой схеме. Схема очень близка к той, что обсуждалась выше.


UPD2: В контроллере, как правило, лучше использовать динамическое связывание или абстрактную фабрику. Обычно это выглядит следующим образом:

<?

$model = ModelAbstractFactory::getFactory();

$controller = new Controller($model);

View::display($controller);

?>

Есть способ выделить контроллер не в виде класса, а в виде модуля:

<?

$model = ModelAbstractFactory::getFactory();
$model->calculate();

View::display($model);

?>

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

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


UPD3: Существует целая песня про MVC, которую написал и исполнил James Dempsey.

июль-август 2007 года,
апрель 2008 года,
апрель 2009 года


Оценка материала:

 
На данный момент нет голосовавших

Число просмотров: 0
Николай, 08.08.2007, 15:20

Спасибо огромное за статью!

Очень легко написана и доносит смысл.

TWINc, signate[::::]gmail.com, 28.08.2007, 16:55

Спасибо! То что надо для быстрого старта.

DieseLL, diesell3[::::]yandex.ru, 29.08.2007, 16:17

Senks!

Андрей, pixmail[::::]mail.ru, 30.08.2007, 18:26

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

Crusader, promo[::::]luckystudent.com.ua, 01.09.2007, 14:03

Опечатка:

"В модели есть три функции...". Следует читать "В отображении есть 3 ф-ции"

Crusader, promo[::::]luckystudent.com.ua, 01.09.2007, 14:06

Еще момент: никто не порождает View

admin, chilimers[::::]mail.ru, 02.09.2007, 21:30

Опечатки исправил, спасибо, что заметили.

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

и во-вторых, в ключе порождения представления контроллером (именно эта точка зрения представлена в статье) всё прекрасно сочетается и подходит (View порождает контроллер, если я правильно понял последний комментарий).

AlexS, 24.09.2007, 09:27

Опечатка..."Метод prosessData() служит для "

MX, mx[::::]tut.by, 06.10.2007, 13:31

Никто не порождает View -- это фактически статик-класс. ;-)

lem, lmichaj[::::]mail.ru, 31.10.2007, 23:46

Статья очень понравилась.

Но я совсем новичок.

Попробовал разместить файл vmc.html на сервере – с вашим текстом просто внутри BODY, но получаю сообщение об ошибке. Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /homepages/18/d41311984/htdocs/jesus1053/mvc1.php on line 13

Чего не хватает, плз.

admin, chilimers[::::]mail.ru, 01.11.2007, 20:51

lem, кажется, у Вас стоит PHP4. В нём статические функции (функции-члены классов) не работают. Уберите слово static из исходного текста и замените оператор :: на -> и всё будет работать.

lem, lmichaj[::::]mail.ru, 02.11.2007, 01:30

Спасибо за быстрый ответ.

Но все равно – не работает.

После предложенных изменений ваш текст как файл .php выдает:

Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in ...mvc.php on line 5

А если внутри Body, то вообще целую страницу сообщений. Я и на другом сайте пробовал, где PHP работает (может и не 5).

Уж простите. Может пошлете мне текст полного файла на мэйл, если время найдется?

Спасибо.

admin, chilimers[::::]mail.ru, 02.11.2007, 11:23

Забыл, ещё надо было убрать ключевое слово private. Но я Вам выслал скрипт примера такой, какой работает на этом сайте (а здесь стоит php4 и мне пришлось его немного подправить).

lem, lmichaj[::::]mail.ru, 03.11.2007, 01:14

Огромное спасибо!

Теперь все работает.

Спокойно могу учиться и даже сравнить версии PHP.

Удачи вам.

Dimon, dima[::::]ni.kiev.ua, 19.11.2007, 18:57

Было бы неплохо узнать ссылочки на более детальную информацию или на книжечки...если кто слышал про Flex, то тоже буду рад информации и по нему. Спс

admin, chilimers[::::]mail.ru, 19.11.2007, 20:41

По шаблонам есть хорошая новая книга Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес

"Приемы объектно-ориентированного проектирования. Паттерны проектирования".

Сам не читал, но на работе советуют. А вообще: UML, ООП, шаблоны проектирования – вот ключевые слова для поиска.

UPD. Прочитал уже давно. Очень советую.

admin, chilimers[::::]mail.ru, 05.12.2007, 21:44

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

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

Для осуществления действий отслеживания изменений, необходимо использовать шаблон Observer. Но и его применение существенно ограничено самой сутью веб-приложений.

Alex, pr10[::::]inbox.ru, 01.03.2008, 02:54

Хорошая статья. Прочитал. Спасибо.

VadimS, 04.03.2008, 16:02

Хорошая статья и понятно написано. Спасибо!

barbiturat, salochka[::::]yandex.ru, 09.04.2008, 14:09

Зачем создавать модель каждый раз в функции userRequest? Почему нельзя обойтись одним объектом модели?

admin, 09.04.2008, 20:57

2barbiturat:

Здесь userRequest() выделена скорее для пояснения смысла, на самом же деле, контроллер вполне может быть шаблоном-одиночкой (или, например, можно для ясности переместить userRequest() в конструктор) и вызывается он один раз, следовательно, модель тоже будет создаваться лишь один раз.

Вообще, в MVC все её три сущности создаются, как правило, только в единственном экземпляре.

Antoni, geeforce[::::]yandex.ru, 15.04.2008, 19:39

Первая статья про MVC. Спасибо, все понятно. Будем углубляться)

А вообще очень даже неплохо будет смотрется если разбить эту модель на 3 файла и юзать ajax

apapacy, apapacy[::::]gmail.com, 05.05.2008, 15:26

В Вашей статье содержится ряд принципиальных неточностей. Я бы не акцентировал на этом внимание. если бы на статью не было ссылки в Вики.

Во-первых, Вы не акцентировали, что схема, из Ajax in Action относится не к MVC, а скорее к Model I и Model II реализации MVC в веб-приложениях.

Во-вторых, метод getData() как раз нарушает независимость Модели. Не Модель должна запрашивать данные на контроллере, а контроллер должен вызывать метод setData() Модели.

apapacy, apapacy[::::]gmail.com, 05.05.2008, 15:30

Сорри, одна неточность.

У Вас getData() все же принадлежит Модели.

Но это в тексте программы.

На диаграмме стрелка идет от Модели к Контроллеру. Диаграмма не соответствует тексту программы.

admin, 05.05.2008, 21:00

apapacy:

1. Подпись к схеме из книги «Аjax in Action» гласит: «Основные компоненты архитектуры "модель -представление-контроллер". Представление и модель не могут обращаться друг к другу – они взаимодействуют только через контроллер. Контроллер рассматривается как промежуточный уровень между моделью и представлением. Благодаря такому подходу разграничиваются функции различных частей программы, обеспечивается дополнительная степень гибкости и упрощается сопровождение приложения».

2. Диаграмма последовательностей верна. Она показывает последовательность событий и потоки данных – из модели в контроллер в случае getData().

apapacy, apapacy[::::]gmail.com, 06.05.2008, 22:41

1. Я читал Ajax in action. И знаю эту схему. И эта схема отличается существенно от общепринятой. Например сравните с GoF, Sun Blueprints, англ. и русск. Wiki. Все имеют одно мнение, что представление не может изменять модель, но может обращаться к модели get-терами.

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

apapacy, apapacy[::::]gmail.com, 06.05.2008, 22:44

Кстати,видимо, авторы приведенной схемы немного смешали MVC и многоуровневое приложение. И модель с бизнес-логикой.

admin, 07.05.2008, 23:25

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

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

Насчёт диаграммы последовательностей можно согласиться, но в том же примере с рестораном в статье про sequence diagram на вики, стрелки поставлены аналогичным образом, как и в этой статье, видимо, для удобства.

apapacy, apapacy[::::]gmail.com, 09.05.2008, 04:06

Извините за назойливость. Но в первом посте я с этим и согласился, когда отнес схему из Ajax-in-Action не к стандартной архитектуре MVC, а к реализации в веб-приложениях ModelI и ModelII.

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

iCanary, 14.05.2008, 10:29

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

- Точняк.

admin, 14.05.2008, 21:19

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

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

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

Таким образом, контроллер всегда может "знать" где находятся модель и отображение, и разбить их на части не составляет никакого труда – это также тривиально, как и подключение скриптов с помощью include_once.

admin, 14.05.2008, 21:19

По просьбам трудящихся, исправил диаграмму последовательностей.

LA, denymoon[::::]mail.ru, 13.07.2008, 14:12

Спасибо, мне понравилось))))

boss, 05.09.2008, 11:01

Хорошая статья, но не могли бы вы показать как разбить этот файл на контролеры, модели и отображение ...

alexv, 08.09.2008, 20:00

Это очень хорошая статья

Вася, 16.09.2008, 01:39

Плохая статья, я бы даже сказал вредная. Где тут реальная реализация паттерна МВС? Код из 2 строчек не моет дать представление, наоборот, только запутывает и дает неправильное представление.

admin, 16.09.2008, 18:50

Смотря что понимать под выражением "реальная реализация паттерна МВС". К тому же, не забывайте, что статья для начинающих, а значит, чем меньше кода – тем лучше. Разве не так?

Evgeny Sergeev, sal1982[::::]list.ru, 17.09.2008, 11:49

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

Sergey, itk-oc[::::]yandex.ru, 26.09.2008, 11:43

Здравствуйте!

Не могли бы вы мне тоже на mail послать код, который вы посылали lem 25-ю сообщениями выше, если не трудно, похоже у меня проблема как у него.

ilkin, ilkinbusiness[::::]hotmail.com, 08.10.2008, 23:15

Otlichnaya statya. Izvinayus za translit. Spasibo za detalnoe obyasneniye etoi konstrukcii. Ochen ponatno i dostupno!

qfox, 13.10.2008, 13:15

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

Я бы не стал проповедовать такой MVC.

admin, 13.10.2008, 19:15

qfox, пример можно?

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

Макс Шаров, max.sharov[::::]gmail.com, 06.11.2008, 12:19

Полезная статья у Вас. Многое разъясняет по структуре MVC. Но у меня почему то при вводе текста на кириллице символы подсчитываются один за два. В итоге в слове "Макс" функция strlen() насчитывает 8 символов. В то время как латинский алфавит считает хорошо. Не подскажете в чем проблема?

admin, chilimers[::::]mail.ru, 08.11.2008, 22:42

Судя по всему, проблема в кодировке

Денис, 16.11.2008, 19:23

Спасибо за статью и за труд!

Побольше бы таких людей.

Артем, 09.12.2008, 17:39

спасибо, теперь стало намного все понятней

Александр Махомет, a.mahomet[::::]gmail.com, 12.12.2008, 01:24

Возможность обращаться к модели из вида очень часто используется в веб приложениях, иначе как вы построите блоки которые общие для нескольких страниц, типа последние новости, лучшие автора и тд. Будут обращаться к контроллеру?

В Smarty для этого есть например плагины, в Zend Framework view хелперы.

Мне кажется этот вопрос вам стоило бы пересмотреть в статье.

Андрей, pixmail[::::]mail.ru, 11.01.2009, 19:16

To: Александр Махомет.

А что мешает в контроллере сделать сервисные методы, которые возвращают по запросу конкретные типы данных, например: "последние новости, лучшие авторы и.т.п" и вызывать данные методы из разных страниц приложения. Таким образом решаются 2 проблемы - доступ view к напрямую к модели не осуществляется и появляется возможность повторно использовать написанный код этих сервисных методов.

Алексей, 21.02.2009, 14:33

Набираем в google "Глава 2 - Исследуем код symfony" первая ссылка - там показывается как из обычного PHP приложения делают приложение с MVC. В общем смысл тоже понятен.

Александр, free.developing[::::]gmial.com, 31.05.2009, 10:33

Макс Шаров,

Полезная статья у Вас. Многое разъясняет по структуре MVC. Но у меня почему то при вводе текста на кириллице символы подсчитываются один за два. В итоге в слове "Макс" функция strlen() насчитывает 8 символов. В то время как латинский алфавит считает хорошо. Не подскажете в чем проблема?

Если у вас кодировка UTF-8, то обычные функции типа strlen, substr будут считать все нелатинские символы по 2 байта каждый. для правильной работы со строками в UTF-8 следует использовать функции библиотеки mb_string. тоесть те же самые функции по только с приставкой mb_ . mb_strlen("Макс"); etc.

worldmind, ashrub[::::]yandex.ru, 27.06.2009, 12:03

Я что-то запутался, в англоязычной википедии сказано

"

the presentation/user interface (UI) (view), business logic (controller), and data access (model).

"

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

admin, 01.07.2009, 21:38

2worldmind, истина где-то рядом.

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

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

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

Главное, в модели MVC - осуществить разделяемость составных её частей, должна присутствовать так называемая "связность" компонентов, что означает на практике то, что любой компонент можно выделить в отдельный модуль (причем это выделение не должно затронуть другие составные части проекта).

Пётр, kpetrk1[::::]mail.ru, 14.07.2009, 17:43

Не катит статья. Там вся МВЦ на маленький скриптик. А если мне надо чтобы был шаблон и в нём куча разных модулей... типа голосование, меню, авторизация.

Не ясно совсем.

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

Дальше чем инициализации хеша и потом замене соответствующих мест на значения элементов хеша пойти не могу.

ЧТО ДЕЛАТЬ? Где прочитать про это? Никто не пишет!

admin, 14.07.2009, 22:59

Пётр, во-первых, ответ дан выше в комментариях.

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

В-третьих, можете сделать билдер, который и будет "строить" все ваши модули. И все элементы, разумеется, должны работать используя MVC.

Глеб, 04.08.2009, 19:54

Спасибо за хорошую статью.

PS. Нашёл очепятку )

цитата: "...Например, в модели мы можем в функции displayDefault() написать..." //конец цитаты

Tir, 07.09.2009, 12:47

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

Уточненеие "Для поддержки разработки требуются более квалифицированные специалисты"... для поддержки требуется больше времени и ресурсов(человеческих) и ни о какой квалификации речь не идёт.

Архитектура проста как бревно, но реализовывать её через класы - то же что автомобиль через выхлопную трубу чинить.

А за статейку спасибо!

Victor, 07.09.2009, 13:49

Спасибо, действительно помогает вникнуть в суть!

Сергей, did_uhim[::::]ukr.net, 24.09.2009, 17:49

Да, классная статья!

Конечно, пообсуждать всегда хочется, высказать, так сказать, своё мнение. Оно, иногда, и нужно. Но ведь написано - статья для начинающих! И в этом плане всё чики-пики. А то тут некоторые критиковать пытаются... И то не так и то не этак. Лично мне всё оч. понравилось и дало общее представление об MVC. Автору - БОЛЬШОЕ СПАСИБО :)

Art, 13.10.2009, 23:34

Добрый день, статья хорошая. Я думаю она не претендует на звание самой правильной статьи по MVC, тк таких статей очень много. Автор просто делиться своим опытом и то как он это видит. а для тех кто хочет побольше почитать по теме и посмотреть достаточно качественный код, открывайте ссылки в Wiki(ru) по теме MVC.

Ещё раз автору спасибо.

asci, asci[::::]yandex.ru, 22.10.2009, 20:13

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

Модель - общение с базой и представление объектов приложения в таблице бд.

Контроллер - логика приложения.

Вид - представление объектов приложения в браузере и интерактивность.

admin, 23.10.2009, 14:19

asci, верные мысли, но почти то же самое и изложено в статье.

serg, 02.11.2009, 19:41

Пример то дейтсвительно простой и понятный. Только один вопрос есть. А как на это всё прикрутить класс для mysql ... Ну допустим есть отдельный класс. Который реализует всё что нужно (connectselectinsertupdate). И вот инетересно как этот класс слепить с кодом выше, чтоб он мог быть "доступен" из любого подкласа и в любом месте в коде. Статикой? Не катит, т.к. придётся постоянно передавать (к примеру db::db_connect($host, $user, $pass, $dbname) такой метод) переменные. Оставлять их в самом классе connect'a не выход по соображениям безопасности... Тогда как?

admin, chilimers[::::]mail.ru, 02.11.2009, 20:12

serg, чуден мир ООП, и у вас есть большие возможности по его освоению.

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

Это особенно удобно, ибо тогда, если соединение с БД вообще не используется, оно и не устанавливается.

srdn, 30.12.2009, 17:37

Как говорят некоторые в наше время, БОЛЬШОЙ РЕСПЕКТ автору статьи. Статья действительно даёт некоторые вводные данные по MVC, к сожалению, в книгах черезчур много кода и, порой не разобраться в самой сути...

LuxeMate, 20.03.2010, 00:30

serg, есть шаблон проектирования Singleton. Один раз при инициализации фреймворка создаёте объект методом getInstance() (конструктор делаем приватным и недоступным) и создаёте коннект к бд, затем везде можно будет делать что-то вроде этого:

$db = Db::getInstance();

$db->query('...');

это всегда будет один и тот же объект, и он не будет создаваться заново.

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

За статью спасибо, когда я начинал возиться с MVC она здорово мне помогла. :)

Masha, 31.03.2010, 12:02

Thanks it was great :)))

Amirkhanov, 19.04.2010, 01:57

На первой диаграмме последовательностей в самом конце обьект View вызывает метод из обьекта User =)

Это ошибка. Страница должна быть показана не в пользователе а по крайней мере в своем же обьекте — стрелкой самой в себя.

Yurii, 20.04.2010, 23:38

"И напоследок: чаще мыслите не кодом, а схемами, шаблонами, абстракциями. Понятно, что это непросто, непривычно и сложно, но учиться этому нужно обязательно." - за это респект!!! Дельная весщь!!!

Костя, 28.06.2010, 17:01

Довольно интересная статья, я как начинающий наконец понял принципы мвц. Буду дальше учить и развивать свои знания. Очень было бы интересно почитать как мвц реализовать в реальном проекте и как правильно использовать ее преимущества.

А также написать простейший каркас (фреймворк) мвц пхп приложений. (Не такой простейший как тут :).

А вообще спасибо. статья - то что надо. По больше бы таких)))

Boss, 15.01.2011, 09:58

<h1>

Чувак всамом начале пиши зачем оно надо!!!!!!!!

</h1>

igor, 10.02.2011, 13:19

Спасибо большое! Статья отличная! Автору огромная благодарность! :)

Пойду мыслить абстракциями...

fan_cpp, trash.daddi[::::]gmail.com, 04.03.2011, 04:03

Спасибо большое! Статья очень хорошая, я как раз пытаюсь реализовать MVC модель в своем приложении, очень помогла ваша статья.

doomka, doomka[::::]ukr.net, 06.05.2011, 17:05

использлвать так модель считаю очень неудобно, как минимум

$controller = new Controller();

$controller->processData();

вот так использую (грубо)

$controller = new Controller();

$controller->Data($_POST['name']);

$controller->processData();

или

$controller = new Controller();

$controller->processData($_POST['name']);

надеюсь понятно почему

Lx, 25.05.2011, 05:05

"Модель - общение с базой и представление объектов приложения в таблице бд.

Контроллер - логика приложения.

Вид - представление объектов приложения в браузере и интерактивность."

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

Кроме того, автор изначально дает неправильное представление MVC. Модель должна отдавать данные представлению напрямую, минуя контроллер. Изменения в модели должны ловиться обсервером и модель на основе полученных сообщений будет напрямую брать данные из модели. Контроллер действует только в одну сторону, обрабатывая колдовство пользователя над представлением. Это - классическая схема отношений MVC с активной моделью.

Если модель пассивная - тогда модель вообще обособленна и за всеми изменениями наблюдает контроллер, модель "не знает" ни о контроллере, ни о представлении вообще ничего.

Да, представленная схема тоже имеет место быть, но раз уж вы взялись объяснять MVC для начинающих, так уж будьте добры описать классическую схему. А то потом наткнувшись на нее люди будут думать, что она некорректна.

Anon, 08.09.2011, 21:58

Очередной раз даете понять что MVC создает больше проблем чем их решает.

Ратмир, ratmir[::::]ecoby.info, 07.10.2011, 15:41

Огромная благодарность за статью, очень грамотна написала, лёгкие и понятные примеры - в общем, то, что надо ;)

attare, 15.11.2011, 15:59

Присоединяюсь к благодарностям...Объяснили..Спасибо

Mike, 27.02.2012, 22:05

Всем привет, появился такой вопросец.

А может ли сама модель дёргать контроллер?

Жизненная ситуация: контроллер запускает модель, модель начинает трудиться (слушать порты) и вот в какой-то момент данные из модели должны быть отображены в форме, естественно через контроллер. Данный шаблон предусматривает решение такой задачи?

serg1008, 28.02.2012, 10:35

mvc это такая же дрянь как теги microsoft

всегда раздражало когда тег <asp:label> потом превращается в <span> -это называется "новыми технологиями"

Мщалф, 14.04.2012, 01:18

ru[dot]wikipedia[dot]org/wiki/Model-View-Controller

"Наиболее частые ошибки" -> «Толстые тупые уродливые контроллеры»...

"абстракции базы данных, делая вид, что это модель"

допрограммировались... делаем вид...

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

okulo, turdakhov[::::]gmail.com, 01.11.2012, 12:14

Дорогой автор, спасибо тебе большое!

MIke, 13.02.2013, 01:50

Хорошая статья для общего понимания, не зря потратил 10 минут.

--

спс

Ktipolkpn, smorfiklop[::::]mail.ru, 30.07.2013, 18:59

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

Balalayk, 17.11.2014, 23:41

Спасибо огромное Вам за столь хорошее разъяснение!

AgaUgu, 21.05.2016, 13:16

Спасибо Вам огромное. То что надо для начала чтобы понимать и разбирается в этом МВК и ООП.

Просто и понятно. Без груза.

Спасибо.

Имя *

Цифровой ящик

Комментарии *