2. 1. ModelView Controller Pattern
Шаблон MVC описывает простой способ построения структуры
приложения, целью которого является отделение бизнес-логики от
пользовательского интерфейса. В результате, приложениелегче
масштабируется, тестируется, сопровождается и конечноже реализуется.
3. MVC
В архитектуре MVC модель предоставляет данные и правила бизнес-
логики, представление отвечает за пользовательский интерфейс, а
контроллер обеспечивает взаимодействие между моделью и
представлением.
Типичную последовательность работы MVC-приложения можно
описать следующим образом:
При заходе пользователя на веб-ресурс, скрипт инициализации
создает экземпляр приложения и запускает его на выполнение.
При этом отображается вид, скажем главной страницы сайта.
Приложение получает запрос от пользователя и определяет
запрошенные контроллер и действие. В случае главной страницы,
выполняется действие по умолчанию (index).
Приложение создает экземпляр контроллера и запускает метод
действия,
в котором, к примеру, содержаться вызовы модели, считывающие
информацию из базы данных.
После этого, действие формирует представление с данными,
полученными из модели и выводит результат пользователю.
4. MVC
Модель — содержит бизнес-логику приложения и включает методы выборки (это могут быть методы ORM), обработки (например,
правила валидации) и предоставления конкретных данных, что зачастую делает ее очень толстой, что вполне нормально.
Модель не должна напрямую взаимодействовать с пользователем. Все переменные, относящиеся к запросу пользователя должны
обрабатываться в контроллере.
Модель не должна генерировать HTML или другой код отображения, который может изменяться в зависимости от нужд пользователя.
Такой код должен обрабатываться в видах.
Одна и та же модель, например: модель аутентификации пользователей может использоваться как в пользовательской, так и в
административной части приложения. В таком случае можно вынести общий код в отдельный класс и наследоваться от него, определяя
в наследниках специфичные для подприложений методы.
Вид — используется для задания внешнего отображения данных, полученных из контроллера и модели.
Виды cодержат HTML-разметку и небольшие вставки PHP-кода для обхода, форматирования и отображения данных.
Не должны напрямую обращаться к базе данных. Этим должны заниматься модели.
Не должны работать с данными, полученными из запроса пользователя. Эту задачу должен выполнять контроллер.
Может напрямую обращаться к свойствам и методам контроллера или моделей, для получения готовых к выводу данных.
Виды обычно разделяют на общий шаблон, содержащий разметку, общую для всех страниц (например, шапку и подвал) и части
шаблона, которые используют для отображения данных выводимых из модели или отображения форм ввода данных.
Контроллер — связующее звено, соединяющее модели, виды и другие компоненты в рабочее приложение. Контроллер отвечает за
обработку запросов пользователя. Контроллер не должен содержать SQL-запросов. Их лучше держать в моделях. Контроллер не
должен содержать HTML и другой разметки. Её стоит выносить в виды.
В хорошо спроектированном MVC-приложении контроллеры обычно очень тонкие и содержат только несколько десятков строк кода.
Чего, не скажешь о Stupid Fat Controllers (SFC) вCMS Joomla. Логика контроллера довольно типична и большая ее часть выносится в
базовые классы.
Модели, наоборот, очень толстые и содержат большую часть кода, связанную с обработкой данных, т.к. структура данных и бизнес-
логика, содержащаяся в них, обычно довольно специфична для конкретного приложения.
5. 2.FrontController (Контроллер входа / Единая точка входа)
Один контроллер обрабатывает все запросы к веб-сайту.В
сложных веб-сайтах есть много одинаковых действий,
которые надо производить во время обработки запросов.
Это, например, контроль безопасности, многоязычность и
настройка интерфейса пользователя. Когда поведение
входного контроллера разбросано между несколькими
объектами, дублируется большое количество кода.
Помимо прочего возникаютсложности смены поведения в
реальном времени.Паттерн FrontController объединяет всю
обработку запросов, пропуская запросы через
единственный объект-обработчик.
Этот объект содержит общую логику поведения, которая
может быть изменена в реальном времени при помощи
декораторов.
После обработки запроса контроллер обращается к
конкретномуобъекту для отработки конкретного
поведения.
6. 3. Factory Method (Фабричный метод)
Фабричный метод (англ. Factory Method) — порождающийпаттерн
(шаблон) проектирования, предоставляющий подклассам интерфейс для
создания экземпляров некоторого класса. В момент создания наследники
могут определить, какой класс создавать. Иными словами,Фабрика
делегирует создание объектов наследникам родительскогокласса. Это
позволяет использоватьв коде программы не специфические классы, а
манипулировать абстрактными объектами на более высокомуровне.
Также известен под названием виртуальныйконструктор (англ.Virtual
Constructor).
7. Factory Method (Фабричный метод)
Цель
Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс
инстанциировать.
Фабричный метод позволяет классу делегировать создание подклассов.
Используется, когда:
• классу заранее неизвестно, объекты каких подклассов ему нужно cоздавать.
• класс спроектирован так, чтобы объекты, которые он создаёт, специфицировались подклассами.
• класс делегирует свои обязанности одному из нескольких вспомогательных подклассов, и
планируется локализовать знание о том, какой класс принимает эти обязанности на себя.
8. Factory Method (Фабричный метод)
Плюсы
• позволяет сделать код создания объектов более
универсальным, не привязываясь к конкретным
классам(ConcreteProduct), а оперируя лишь общим
интерфейсом (Product);
• позволяет установить связь между параллельными
иерархиями классов.
Минусы
• необходимость создавать наследника Creator для каждого
нового типа продукта (ConcreteProduct).
• Product — продукт
• определяет интерфейс объектов,создаваемыхабстрактным
методом;
• ProductA, ProductB — конкретный продукт
• реализует интерфейс Product;
• FactoryAbstract — создатель
• объявляет фабричный метод,которыйвозвращает объект типа
Product.Можеттакже содержатьреализациюэтогометода«по
умолчанию»;
• можетвызывать фабричный методдля созданияобъектатипа
Product;
• Factory — конкретный создатель
• переопределяет фабричный метод такимобразом, чтобы он
создавал и возвращал объект классаConcreteProduct.
9. 4. Abstract Factory (Абстрактная фабрика)
Абстрактная фабрика (англ. Abstract factory) — порождающий шаблон
проектирования, позволяющий изменять поведение системы, варьируя
создаваемые объекты, при этом сохраняя интерфейсы. Он позволяет создавать
целые группы взаимосвязанных объектов, которые, будучи созданными одной
фабрикой, реализуют общее поведение. Шаблон реализуется созданием
абстрактного класса FormBuilder, который представляет собой интерфейс для
создания компонентов системы(например, для оконного интерфейса он может
создавать окна и кнопки). Затем пишутся наследующиеся от него классы,
реализующие этот интерфейс.
10. Abstract Factory (Абстрактная фабрика)
Цель
Предоставляет интерфейс для создания семейств взаимосвязанных или
взаимозависимыхобъектов, не специфицируя ихконкретных классов.
11. Abstract Factory (Абстрактная фабрика)
Плюсы
• изолирует конкретные классы;
• упрощает замену семейств продуктов;
• гарантирует сочетаемость продуктов.
Минусы
• сложно добавить поддержку нового вида
продуктов.
Применение
Система не должна зависеть от того, как
создаются, компонуются и представляются
входящие в нее объекты. Входящие в семейство
взаимосвязанные объекты должны
использоваться вместе и вам необходимо
обеспечить выполнение этого ограничения.
Система должна конфигурироваться одним из
семейств составляющих ее объектов. Требуется
предоставить библиотеку объектов, раскрывая
только их интерфейсы, но не реализацию.
12. 5. Prototype (Прототип)
Паттерн Prototype позволяет создавать новые объекты на основе
некоторого объекта-прототипа приэтом совсем необязательно знать как
необходимый объект устроен.
Цель
Задаёт виды создаваемыхобъектов с помощью экземпляра-прототипа и
создаёт новые объекты путём копированияэтого прототипа.
Проще говоря, это паттерн создания объекта через клонирование
другого объекта вместо создания через конструктор.
13. Prototype (Прототип)
Применение
Паттерн используется чтобы:
• избежать дополнительных усилий по созданию объекта
стандартным путем (имеется в виду
использованиеключевого слова 'new', когда вызывается
конструктор не только самого объекта, но и конструкторы
всейиерархии предков объекта), когда это непозволительно
дорого для приложения.
• избежать наследования создателя объекта (object creator) в
клиентском приложении, как это делает паттернАбстрактная
фабрика.
Используйте этот шаблон проектирования, когда система не
должна зависеть от того, как в ней создаются, компонуются и
представляются продукты:
• инстанцируемые классы определяются во время
выполнения, например с помощью динамической загрузки;
• для того чтобы избежать построения иерархий классов или
фабрик, параллельных иерархии классовпродуктов;
• экземпляры класса могут находиться в одном из нескольких
различных состояний. Может оказаться удобнееустановить
соответствующее число прототипов и клонировать их, а не
инстанцировать каждый раз классвручную в подходящем
состоянии.
14. 6. Объектный пул (Pool)
Порождающий паттерн, который предоставляет набор
заранее инициализированных объектов, готовых к
использованию («пул»), что не требует каждый раз
создавать и уничтожать их.
Хранение объектов в пуле может заметно повысить
производительность в ситуациях, когда стоимость
инициализации экземпляра класса высока, скорость
экземпляра класса высока, а количество одновременно
используемых экземпляров в любой момент времени
является низкой. Время на извлечение объекта из пула
легко прогнозируется, в отличие от создания новых
объектов (особенно с сетевым оверхедом), что занимает
неопределённое время.
Однако эти преимущества в основном относится к
объектам, которые изначально являются
дорогостоящими по времени создания. Например,
соединения с базой данных, соединения сокетов,
потоков и инициализация больших графических
объектов, таких как шрифты или растровые
изображения. В некоторых ситуациях, использование
простого пула объектов (которые не зависят от внешних
ресурсов, а только занимают память) может оказаться
неэффективным и приведёт к снижению
производительности.
15. 7. Одиночка (Singleton)
Назначение
Позволяет содержать только один экземпляр объекта в
приложении, которое будет обрабатывать все
обращения, запрещая создавать новый экземпляр.
Примеры
DBConnector для подключения к базе данных
Logger (также может быть Multitonесли есть много
журналов для нескольких целей)
Блокировка файла в приложении (есть только один в
файловой системе с одновременным доступом к нему)
16. 8. Статическая Фабрика (Static Factory)
Назначение
Подобно AbstractFactory, этот паттерн
используется для создания ряда связанных
или зависимых объектов. Разница между этим
шаблоном и Абстрактной Фабрикой
заключается в том, что Статическая Фабрика
использует только один статический метод,
чтобы создать все допустимые типы объектов.
Этот метод, обычно, называется factory или
build.
Примеры
Zend Framework: Zend_Cache_Backend или
_Frontend использует фабричный метод для
создания cache backends или frontends
17. 9. Декоратор (Decorator)
Назначение
Динамически добавляет новую
функциональность в экземпляры классов.
Примеры
• Zend Framework: декораторы для
экземпляров Zend_Form_Element
• Web Service Layer: Декораторы JSON и XML
для REST сервисов (в этом случае, конечно,
только один из них может быть разрешен).
18. 10. Итератор (Iterator)
Назначение
Добавить коллекции объектов функционал
последовательного доступа к содержащимся в
ней экземплярам объектов без реализации этого
функционала в самой коллекции.
Примеры
построчный перебор файла, который
представлен в виде объекта, содержащего
строки, тоже являющиеся объектами. Обработчик
будет запущен поверх всех объектов.
Примечание
Стандартная библиотека PHP SPL определяет
интерфейс Iterator, который хорошо подходит для
данных целей.Также вам может понадобиться
реализовать интерфейс Countable, чтобы
разрешить вызывать count($object) в вашем
листаемом объекте.
19. 11. Наблюдатель (Observer)
Назначение
Для реализации публикации/подписки на
поведение объекта, всякий раз, когда объект
«Subject» меняет свое состояние, прикрепленные
объекты «Observers» будут уведомлены. Паттерн
используется, чтобы сократить количество
связанных напрямую объектов и вместо этого
использует слабую связь (loose coupling).
Примеры
Система очереди сообщений наблюдает за
очередями, чтобы отображать прогресс в GUI
Примечание
PHP предоставляет два стандартных интерфейса,
которые могут помочь реализовать этот шаблон:
SplObserver и SplSubject.
20. 12. Сущность-Атрибут-Значение(EAV)
Шаблон Сущность-Атрибут-Значение
используется для реализации модели EAV на PHP
Назначение
Модель Сущность-Атрибут-Значение (EAV) - это
модель данных, предназначенная для описания
сущностей, в которых количество атрибутов
(свойств, параметров), характеризующих их,
потенциально огромно, но то количество,
которое реально будет использоваться в
конкретной сущности относительно мало.
21. 13. Registry (Реестр)
Хорошо известный объект, который используется
другими объектами для получения общих объектов и
сервисов.
Когда нужно найти какой-нибудь объект, обычно
начинают с другого объекта, связанного с целевым.
Например, если нужно найти все счета для покупателя,
начинают, как раз с покупателя и используют его метод
получения счетов.Тем не менее, в некоторых случаях
нет подходящего объекта, с которого начать. Например,
известен ID покупателя, но нет ссылки на него.Тогда
нужен своего рода объект-поисковик, но тогда
возникает вопрос - как вы найдёте сам поисковик?
Реестр (Registry) - это глобальный объект по сути своей
или, по крайней мере, так выглядит - он может
функционировать только будучи глобальным.
22. 14. Lazy Load (Ленивая загрузка)
Объект,не содержитданных, но знает, где их взять.
Для загрузки данных из БД в память приложенияудобно пользоватьсязагрузкойне
толькоданных об объекте, но и о сопряжённых с ним объектах. Этоделает загрузку
данных прощедля разработчика:он просто используетобъект,который,тем не менее
вынужден загружатьвсе данные в явном виде.
Но это ведёт к случаям, когдабудет загружатьсяогромноеколичествосопряжённых
объектов,что плохо скажетсяна производительностив случаях, когда эти данные
реально не нужны.
ПаттернLazy Load(Ленивая Загрузка) подразумевает отказот загрузки дополнительных
данных, когдав этом нет необходимости.Вместоэтогоставитсямаркер о том, что
данные не загружены и их надо загрузить в случае, если они понадобятся.Как известно,
если Вы ленивы, то вы выигрываетев том случае, если дело, котороевы не делали на
самомделе и не надо было делать.
Существуетчетыре основныхварианта ленивой загрузки.
• Lazy Initialization(Ленивая Инициализация)используетспециальныймакер (обычно
null), чтобы пометитьполе, как не загруженное. При каждомобращении к полю
проверяется значение маркера и, если значение поля не загружено - оно
загружается.
• Virtual Proxy (Виртуальный Прокси)- объект с таким же интерфейсом,как и
настоящийобъект. При первом обращении к методуобъекта,виртуальный прокси
загружает настоящийобъект и перенаправляет выполнение.
• Value Holder(Контейнер значения) - объектс методомgetValue. Клиент вызывает
метод getValue, чтобыполучить реальный объект. getValue вызывает загрузку.
• Ghost(Призрак) - объект без каких-либоданных. При первом обращении к его
методу,призрак загружает все данные сразу.
23. 15. МОДУЛЬ (MODULE)
Каждый, кто детально знакомитсяс разработкой на Magento,рано или поздно
сталкиваетсяс паттерномМодуль.
Он определяет как разные доменыгруппируютсяв отдельные модулитаким образом,
что не мешают для функционированияодин другомуи могут использовать функционал
для работы из директориис модулями(scope)основной системы.
Но, хотя magento опирается на модульнуюструктуру,ее реализация внутри ядра
платформы немодульна“до костей”.
Определеннаяфункциональностьсильно привязана к центру системыи не может быть
легко изменена.Примером можетпослужить тот же супер-глобальный Mage-класс,
которыйвводит разные общесистемныезависимости.
Эти зависимоститрудноконтролировать.