Mvc модель как бизнес логика

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

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

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

Архитектура ПО, MVC и бизнес-логика. Критика Django

Самое главное, по моему мнению, в изучении парадигм вида MVC, MVP, MVVP/etc и любых других шаблонов.: не пытаться ограничивать себя в реализации. Самого правильного варианта не существует, есть лишь общая модель, идея. А как это называется не особо важно. Не стоит сжимать себя до терминов и определений.

Что есть представление (View)

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

Я предполагаю, что читатель знаком с ООП и уже может что-то писать на PHP. Если нет, то материал в данной статье может вызвать вопросы. Для примеров нужно быть знакомым с PHP 7.1 или выше.

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

Наше представление для корзины выглядело бы как-то так:

// /views/cart.php Корзина

Корзина

№ Наименование Количество Сумма

getItems() as $index => $data) : ?>

getName(), ENT_QUOTES | ENT_SUBSTITUTE); ?>getQuantity(); ?>getSum(); ?>
ИтогоgetTotalQuantity(); ?>getTotalSum(); ?>

Что мы видим в этом куске кода:

  • одна переменная-объект $cart со всеми данными;
  • цикл для отображения списка добавленных товаров в корзину;
  • функцию htmlspecialchars() с константами ENT_QUOTES и ENT_SUBSTITUTE для защиты от XSS-аттаки и просто защиты от «поехавшей» верстки;
  • строку итого с общим количеством и суммой.

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

Что такое “бизнес логика”? И как начать ее понимать

Что есть модель (Model)

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

Для большинства, прочитавших принципы и идею работы MVC/MVP/etc, сложилось стойкое правило, что там должна быть бизнес-логика: обращение к базе данных, наличие ключевых логических функций, валидация входящих данных и т.п. На самом деле, это не так (если, конечно, это не упрощенная модель парадигмы MVC/MVP/etc; хотя и в данном случае все получается более запутанным, нежели простым). Если вернуться в начало статьи, где я говорю, что MVC это шаблон взаимодействия с пользовательским интерфейсом (UI), то все становится ясным: бизнес-логики в модели быть не может.

Читайте также:  Как изменить свое мышление бизнес

Давайте напишем модель для нашего представления из примера выше:

В примере валюта хранится в float в у.е. В реальных проектах удобно хранить в integer в минимальной денежной единице (для рубля РФ это копейки). Еще более удобней в fixed-point — числах с фиксированной точкой. А для работы с такими значениями используют BCMath или GMP.

У нас получилось два класса. Cart содержит все необходимые данные для отрисовки корзины, а CartItem содержит данные позиции товара в корзине. Друг без друга эти два класса смысла не имеют. И используются они только в паре. Вся работа модели сводится к хранению и/или транспортировке. При необходимости модель может что-то считать используя уже полученные данные (как в Cart::getTotalQuantity() и Cart::getTotalSum() ).

Что есть Контроллер (Controller)

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

  1. контроллер в курсе, какое представление он использует, а не должен;
  2. связь между контроллером и представлением получается двунаправленная, а не однонаправленная от представления к контроллеру.

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

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

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

Для нашего примера контроллер будет иметь следующий вид:

// /src/Controller/CartController.php namespace AppController; use AppViewModelCart; use AppViewModelCartItem; class CartController < public function load(): void < $cart = new Cart(); $cart->addItem(new CartItem(‘Item 1’, 1, 600.96)); $cart->addItem(new CartItem(‘Item 2’, 2, 399.00)); ob_start(); require __DIR__ . ‘/views/cart.php’; echo ob_get_clean(); > >

У нас получился класс с одним методом load() в котором мы наполнили данными нашу модель и отрисовали представление. В реальности, конечно, у нас не будет статических данных. Как минимум номера номенклатуры и количество будут храниться в куках (cookies), а сама номенклатура в базе данных.

Читайте также:  Документы необходимые для открытия гостиничного бизнеса

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

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

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

// /src/Service/CartService.php namespace AppService; use AppViewModelCart; use AppViewModelCartItem; class CartService < public function getData(): Cart < $cart = new Cart(); $cart->addItem(new CartItem(‘Item 1’, 1, 600.96)); $cart->addItem(new CartItem(‘Item 2’, 2, 399.00)); return $cart; > >

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

И вроде бы проблема решена. Но нет. Мы «размыли» границу между слоем модели и бизнес-логикой: модель пользовательского интерфейса используется в бизнес-логике. А такого быть не должно из-за правила взаимодействия со слоями приложения (об этом мы поговорим в другой раз).

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

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

// /src/Service/CartService.php namespace AppService; use AppModelCart; use AppModelCartItem; class CartService < public function getData(): Cart < $cart = new Cart(); $cart->addItem(new CartItem(‘Item 1’, 1, 600.96)); $cart->addItem(new CartItem(‘Item 2’, 2, 399.00)); return $cart; > >

Проблема «размытой» границы слоев решена. Появилась другая. Избыточность (или «бойлерплейт»). Теперь нам нужно проделывать двойную работу, чтобы передавать данные из одной части приложения в другую.

Резонный вопрос возникающий в голове программиста: можно ли как-то это сделать лучше? Да, можно, если мы говорим о PHP.

Как вы уже заметили, данные в представление попадают в виде переменных и позже используются для отрисовки. И на объекты, содержащие данные, никто не вешает наблюдателей за изменениями. Это просто не нужно в виду особенности работы PHP: после каждого запроса «умирать». Именно поэтому данные идут в одном направлении и достигая «конечной» прекращают свое существование.

Если бы это было приложение на Java, то там наличие модели для представления является обязательным для реализации MVC. В PHP это аппендикс.

Правда, модели представления иногда необходимы, но не так часто. Когда именно они нужны подсказывает логика. Какого-то определенного правила нет.

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

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

Упраздним модели представления и внесем изменения:

Читайте также:  Как открыть бизнес по продаже книг

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

Добавим точку входа для запуска:

// /public/index.php header(‘HTTP/1.1 200 OK’); header(‘Content-type: text/html; charset=UTF-8’); $ctrl = new AppControllerCartController(new AppServiceCartService()); $ctrl->load(); exit(0);
$ php -S 127.0.0.1:8080 -t public

Такой вот MVC в PHP.

Заключение

Тема шаблона MVC в PHP заезжена вдоль и поперек. Множество реализаций и мнений. Да и саму тему охватить в одной статье тяжело. Много нюансов, много особенностей. В своей статье я хотел дать пищу для размышления и рассуждения в контексте PHP, сделал упор на то, что это шаблон пользовательского интерфейса и никак не относится к бизнес-логике; бизнес-логика находится вне шаблона MVC и в основу её лежит огромный пласт других практик и шаблонов проектирования с которыми стоит ознакомиться; и что MVC не панацея и на нем не держится вся архитектура приложения.

Если у вас остались вопросы — пишите в комментариях и я обязательно отвечу на них.

Источник: mihaly4.ru

Паттерн MVC

Термин используется с конца 70-х гг. прошлого столетия. Эта модель явилась результатом проекта Smalltalk в компании Xerox PARC, где она была задумана как способ организации некоторых из ранних приложений графического пользовательского интерфейса. Некоторые из нюансов первоначальной модели MVC были связаны с концепциями, специфичными для Smalltalk, такими как экраны и инструменты, но более глобальные понятия все еще применимы к приложениям, и особенно хорошо они подходят для веб-приложений (MVC нашел отличное применение в ASP.NET, но ниже мы рассмотрим этот паттерн в WPF).

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

Модели

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

Представления

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

Контроллеры

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

Ниже структура MVC показана на диаграмме:

Структура MVC

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

Уровень представления

Рейтинг
( Пока оценок нет )
Загрузка ...
Бизнес для женщин