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

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

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

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

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

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

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

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

Предлагаю сразу создать три директории в папке src нашего проекта, назовем их Models, Views, Controllers и следующие файлы в них:
/src/Controllers/UserController.php
/src/Models/User.php
/views/User.php
/index.php

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

<?php
// Точка вызова - index.php
// у нас пока нет автолоадинга, подключим наши классы ручками
require('src/Controllers/UserController.php');
require('src/Models/User.php');
// Создаем экземпляр класса контроллера
$controller = new UserController();
// Вызываем метод для отображения данных
$controller->viewUser();
<?php
// Контроллер
// src/Controllers/UserController.php
class UserController
{
 public function viewUser(): void
 {
  $user = $this->loadUser();
  require 'views/user.php';
 }

 private function loadUser(): User
 {
  $user = new User();
  $user->setId(1);
  $user->setFirstName('Ivan');
  $user->setLastName('Ivanov');
  $user->setEmail('i.ivanov@example.com');
  $user->setCreatedAt(strtotime('1/1/2025'));
  return $user;
 }
}
<?php
// Модель
// src/Models/User.php
class User
{
 private int $id;
 private string $firstName;
 private string $lastName;
 private string $email;
 private int $createdAt;

 public function getId(): int
 {
  return $this->id;
 }

 public function setId(int $id): void
 {
  $this->id = $id;
 }

 public function getFirstName(): string
 {
  return $this->firstName;
 }

 public function setFirstName(string $firstName): void
 {
  $this->firstName = $firstName;
 }

 public function getLastName(): string
 {
  return $this->lastName;
 }

 public function setLastName(string $lastName): void
 {
  $this->lastName = $lastName;
 }

 public function getEmail(): string
 {
  return $this->email;
 }

 public function setEmail(string $email): void
 {
  $this->email = $email;
 }

 public function getCreatedAt(): int
 {
  return $this->createdAt;
 }

 public function setCreatedAt(int $createdAt): void
 {
  $this->createdAt = $createdAt;
 }
}
<!--// Шаблон. views/user.php //-->
<DOCTYPE! html>
<html lang="ru">
<head>
 <meta charset="utf-8">
 <title>User view</title>
</head>
<body>
<h1>Пользователь №<?= $user->getId() ?></h1>
<table>
 <thead>
  <tr>
   <th>№</th>
   <th>Фамилия</th>
   <th>Имя</th>
   <th>Email</th>
   <th>Создан</th>
 </tr>
 </thead>
 <tbody>
  <tr>
   <td><?= $user->getId() ?></td>
   <td><?= $user->getLastname() ?></td>
   <td><?= $user->getFirstname() ?></td>
   <td><?= $user->getEmail() ?></td>
   <td><?= date("Y-m-d", $user->getCreatedAt()) ?></td>
  </tr>
 </tbody>
</table>
</body>
</html>

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

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

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


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

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