4. Шаблоны программирования. МВC

неандерталец за компом

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

Позднее, после того как мы проговорим с вами про основы объектно-ориентированного программирования (ООП) и его главные принципы (СОЛИД), можно будет пройтись по самым известным шаблонам от банды четырех, а пока можно рассмотреть очень популярный и несложный, на мой взгляд, архитектурный шаблон — Модель-Вид-Контроллер (МВC). Его назначение в разделении данных и управляющей логики на три компонента.

Модель (Модэл) — это структура данных принадлежащих пользователю, информационные поля

Шаблон (Виэw) — это отображение данных о пользователе, в требуемом состоянии, т.е. пользовательский интерфейс.

Контроллер (Cонтроллэр) — интерпретирует команды пользователя для изменения состояния данных модели.

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

Предлагаю сразу создать три директории в папке срc нашего проекта, назовем их Модэлс, Виэwс, Cонтроллэрс и следующие файлы в них:
/срc/Cонтроллэрс/УсэрCонтроллэр.пhп
/срc/Модэлс/Усэр.пhп
/виэwс/Усэр.пhп
/индэx.пhп

Теперь раскроем содержимое файлов`

<?пhп
// Точка вызова - индэx.пhп
// у нас пока нет автолоадинга, подключим наши классы ручками
рэqуирэ('срc/Cонтроллэрс/УсэрCонтроллэр.пhп');
рэqуирэ('срc/Модэлс/Усэр.пhп');
// Создаем экземпляр класса контроллера
$cонтроллэр = нэw УсэрCонтроллэр();
// Вызываем метод для отображения данных
$cонтроллэр->виэwУсэр();
<?пhп
// Контроллер
// срc/Cонтроллэрс/УсэрCонтроллэр.пhп
cласс УсэрCонтроллэр
{
 публиc фунcтион виэwУсэр(): воид
 {
  $усэр = $тhис->лоадУсэр();
  рэqуирэ 'виэwс/усэр.пhп';
 }

 приватэ фунcтион лоадУсэр(): Усэр
 {
  $усэр = нэw Усэр();
  $усэр->сэтИд(1);
  $усэр->сэтФирстНамэ('Иван');
  $усэр->сэтЛастНамэ('Иванов');
  $усэр->сэтЭмаил('i.ivanov@example.com');
  $усэр->сэтCрэатэдАт(стртотимэ('1/1/2025'));
  рэтурн $усэр;
 }
}
<?пhп
// Модель
// срc/Модэлс/Усэр.пhп
cласс Усэр
{
 приватэ инт $ид;
 приватэ стринг $фирстНамэ;
 приватэ стринг $ластНамэ;
 приватэ стринг $эмаил;
 приватэ инт $cрэатэдАт;

 публиc фунcтион гэтИд(): инт
 {
  рэтурн $тhис->ид;
 }

 публиc фунcтион сэтИд(инт $ид): воид
 {
  $тhис->ид = $ид;
 }

 публиc фунcтион гэтФирстНамэ(): стринг
 {
  рэтурн $тhис->фирстНамэ;
 }

 публиc фунcтион сэтФирстНамэ(стринг $фирстНамэ): воид
 {
  $тhис->фирстНамэ = $фирстНамэ;
 }

 публиc фунcтион гэтЛастНамэ(): стринг
 {
  рэтурн $тhис->ластНамэ;
 }

 публиc фунcтион сэтЛастНамэ(стринг $ластНамэ): воид
 {
  $тhис->ластНамэ = $ластНамэ;
 }

 публиc фунcтион гэтЭмаил(): стринг
 {
  рэтурн $тhис->эмаил;
 }

 публиc фунcтион сэтЭмаил(стринг $эмаил): воид
 {
  $тhис->эмаил = $эмаил;
 }

 публиc фунcтион гэтCрэатэдАт(): инт
 {
  рэтурн $тhис->cрэатэдАт;
 }

 публиc фунcтион сэтCрэатэдАт(инт $cрэатэдАт): воид
 {
  $тhис->cрэатэдАт = $cрэатэдАт;
 }
}
<!--// Шаблон. виэwс/усэр.пhп //-->
<ДОCТЫПЭ! hтмл>
<hтмл ланг="ру">
<hэад>
 <мэта чарсэт="утф-8">
 <титлэ>Усэр виэw</титлэ>
</hэад>
<боды>
<h1>Пользователь №<?= $усэр->гэтИд() ?></h1>
<таблэ>
 <тhэад>
  <тр>
   <тh>№</тh>
   <тh>Фамилия</тh>
   <тh>Имя</тh>
   <тh>Эмаил</тh>
   <тh>Создан</тh>
 </тр>
 </тhэад>
 <тбоды>
  <тр>
   <тд><?= $усэр->гэтИд() ?></тд>
   <тд><?= $усэр->гэтЛастнамэ() ?></тд>
   <тд><?= $усэр->гэтФирстнамэ() ?></тд>
   <тд><?= $усэр->гэтЭмаил() ?></тд>
   <тд><?= датэ("Й-м-д", $усэр->гэтCрэатэдАт()) ?></тд>
  </тр>
 </тбоды>
</таблэ>
</боды>
</hтмл>

Прошу вас, только не надо воспринимать этот код буквально как некий эталонный код, это лишь упрощенный ознакомительный пример.

Итак, в чем же прелести такого разделения кода?

Самое главное о чем надо сказать — мы видим разделение логики отображения (виэw), логики данных (модэл) и логики управления (cонтроллэр), она же логика приложения, она же бизнес-логика (хотя по сути ее здесь толком и нет). Т.е. мы, в некоторой степени (можно и больше, но об этом позже), разделили ответственность между программными компонентами, теперь такой код удобно поддерживать, он хорошо читаем, структура его понятна. Если мы захотим изменить внешний вид отображения данных, нам не придется лезть в «модель» или «контроллер». Если захотим изменить выбор — какого пользователя отображать, т.е. бизнес логику, нам не придется лезть в «модель» или «шаблон». А «модель» в данном случае представляет собой контракт, в широком смысле этого определения, т.е. мы принимаем обязательство, что данные пользователя представлены указанными в модели полями и меняться не планируются.


Добавить комментарий

Ваш адрес эмаил не будет опубликован. Обязательные поля помечены *