Enterprise Patterns in Magento

821 views

Published on

Mageconf2 Presentation

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
821
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Воркшоп. Кто знаком с Фаулером — узнает про Magento Хочу рассказать про Magento Почему начал с шаблонов? Проще начать с установки и примеров?
  • Паттерны вносят в рассказ о архитектуре структуру Позволяют увидеть картину в целом Крег Ларман сформулировал П аттерн — сконцентрированный опыт Имена чтоб быстрее общаться Легче общаться потому что общая терминология Когда видно общее легче найти отличия Мой доклад — ввод в терминологию Magento
  • Паттернов около 50 Выбрал связь с базой данных Начну с логики предметной области Затем Архитектура источника данных Затем объектно-реляционное поведение
  • Рассказ о связи решил начать с того откуда берутся объекты Есть набор требований и делаем ОО декомпозицию C амый простой способ — разбить по действиям системы он самый очевидный
  • Сценарий транзакции — процедура Данные принимает от представления Данные обрабатывает, сохраняет, проверяет, активизирует другие системы Каждое действие реализовано сценарием Возвращает данные слою представления Несколько сценариев в класс паттерн Command — Один сценарий представлен классом Достоинство — простота. Легко воспринимается Основная проблема — дублирование фрагментов кода Второй путь — для сложной логики Приложение растет — сценарии просятся на рефакторинг В результате рефакторинга приходим к Domain Model
  • Сеть взаимосвязанных объектов — каждый представляет сущность Одни имитируют данные области, другие — формализируют правила. Например статус ордера Реализация — пополнение приложения слоем объектов Функции тесно сочитаются с данными на которых они оперируют Простая модель во многом походит на схему базы данных Сложная — значительно отличается и содержит иерархии наследования, сеть сложных взаимосвязанных объектов.
  • При использовании domain model бизнес-логика концентрируется в одном скоупе классов Мадженто модульная каждый модуль имеет слой доменных объектов модели разных модулей могут связываться мужду собой Service Layer – верхушка всякого приложения, непосредственное его API Далее подробнее расскажу о слое связи с данными
  • О бъекты доменной логики имеют свое состояние Рано или поздно данные нужно загрузить или выгрузить из оперативной памяти Средства обеспечивающие Persistence Не всем посчастливилось работать с объектно-ориентированными базами данных Неоднозначное соответствие между структурой объекта и структурой базы данных Проблема отображения объекта в плоскую табличную структуру Кому назначить ответственность за привязку данных объекта к данным таблиц СУБД Не можем сделать этого в доменной модели Один вариант — вынести привязку в отдельные классы
  • = Дата Маппер — объект вызываемый клиентом = Берет данные из базы и помещает в объект = Если объект знает о структуре базы то изменение в одном приводит к необходимости в изменении в другом = Дата Маппер — слой отделяющий объекты от базы данных = Теперь объекты могут не подозревать о существовании базы данных = Преобразователь полностью скрыт от уровня домена
  • = Пример = При необходимости весь слой дата мапперов может быть заменен = Преобразователи должны справляться как с простыми задачами поле-ячейка, так и со сложными наследованием, взаимодействием разных объектов = Маппер может на один запрос к базе данных заполнить несколько объектов данными = Обычно — один маппер для каждой доменной модели = При использовании Metadata Mapping — может быть один класс = Маппер должен иметь доступ к полям объекта
  • - У Magento - ресурс-модели - К аждый модуль имеет свой набор ресурс моделей - По хорошему у каждой модели есть своя ресурс модель - Регистрируется в конфигах - Чтоб вызвать нужно воспользоваться статическим методом класса Mage
  • - Каждый ресурс екстендится от абстрактной модели - Как видим метод лоад принимает на вход объект, который он будет заполнять данными - Select формируется ранее - Read Adapter - это адаптер базы данных, в нашем случае играет роль Data Access Object - a - ничего не мешает написать полностью свой класс ресурс-объекта без абстракта
  • - C труктура стандартной MySQL ресурс-модели - O бычно ресурс-модели екстендятся от абстрактной - П арент - еще более абстрактные операции по манипулированию транзакциями и доступа к адаптеру
  • - Основное отличие от классического шаблона дата маппер - то что доменная модель знает о своей ресурс модели - У абстрактной доменной модели есть метод getResource - Чтоб объяснить зачем это сделано сперва рассмотрим следующий паттерн
  • - При использовании доменной модели нет однозначного соответсвия между таблицей и объектом - Не все поля могут быть заполнены одним запросом - Объект имеет множество ссылок насвязанные объекты - При работе с объектом ожидаем что он уже заполнен данными и связанные объекты тоже - Есть разные пути как загружать дополнительные данные. - Самый очевидный - все данные пытаться загрузить при загрузке объекта - Энергичная загрузка - модели проявляют инициативу - Недостатки - данных может быть загружено слишком много - Другой вариант - при загрузке текущего объекта совсем не доставать связанные - Необходимые данные загружаются в момент первого доступа к ним - Ленивая - пока не пнешь не полетит
  • - Ресурс модель как правило не загружает никаких данных кроме тех какие запросили в select-e при инициализации - Е сли требуется загрузить связанные данные - вызываются методы ресурс-модели - В ресурс-модель по-прежнему передается экземпляр объекта
  • = Table_Data_Gateway шаблон для немного более простых ситуаций нежели Дата Маппер. = Альтернатива - потому что это взаимоисключающие шаблоны. = В Magento не используется = Он как и Дата Маппер внешние классы по отношению к доменной модели. = Основная разница в том, что он ничего не знает про модель его использующую = Модель сама обращается к шлюзу и просит достать данные из таблицы = Шлюз как правило не имеет состояний поскольку лишь передает данные из таблицы в модель = Как правило один шлюз работает с одной таблицей или с главной таблицей и несколькими связанными. Для каждой таблицы создается свой шлюз = Включает методы поиска, обновления и вставки данных и просто вызывает соответсвующие комманды SQL Реализует такую себе виртуальную таблицу = Zend_Db_Table
  • = Оболочка для строки таблицы. = Добавляет к данным логику домена = Объект охватывает и данные и их поведение = В основе лежит шаблон Domain Model , = Классы которого повторяют структуру записей используемой Базы данных. = Структура данных должна точно соответствовать той что в таблице = Тесная зависимость от структуры базы данных что усложняет изменение этой структуры = Joomla
  • = Гарантирует что каждый объект будет загружен из базы данных только один раз = Хранит данные обо всех объектах загруженных из БД в пределах транзакции = Как только возникает необходимость в данных следует сперва обратится к коллекции чтоб убедится что их там еще нет = В случае простой схемы для каждой таблицы своя коллекция = Количество коллекций рекомендуется привязать к объектам а не к таблицам - тогда объекты не знают деталей отображения на базу = Несложно и удобно привязать коллекции к Data Mapper = Коллекция может использоваться в качестве кэша записей считываемых из базы данных
  • - В Magento коллекции рядом с ресурс моделями - С точки зрения АПИ они ничем не отличаются - Лежат в директории рядом с ресурс-моделями, но называются коллекциями - Коллекция предоставляет интерфейс для контролем загрузки, а так же манипулирования уже загруженными данными.
  • И нтерфейсы Countsble и Iterator Самая абстрактная модель - предоставляет базовую функциональность Достать элемент, добавить, пройтись по всем элементам DB-коллекция - позволяет проверить загружена ли она, провести загрузку Так же коллекции предоставляют средства кеширования - данные сериализуются и записываются в файловый кеш Коллекция от которой наследуются остальные коллекции Интерфейсы для добавления модели и ресурс-модели, сохранение, манипулирование объектом select
  • Enterprise Patterns in Magento

    1. 1. Тулика Евгений Magento Developer Professional Services Team evgeniy.tulika@magento.comШаблоны корпоративных приложений в Magento
    2. 2. Шаблоны. Почему о них говорят? Craig Шаблоны не содержат B Larman новых идей C Шаблоны имеют имена Шаблоны облегчают D общение
    3. 3. • Transaction Script• Identity Map • Domain Model• Lazy Load • Data Mapper Domain Logic • Table Data Gateway Object-Relational • Active Record Behavior Data Source Architecture
    4. 4. Представление бизнес-логикиПростой путь: декомпозиция по действиям AccountActions + Login + Register + Logout + ShowAccount CheckoutActions + addToCart + showCheckout + submitCheckout
    5. 5. Transaction ScriptКаждая операция реализована своим методом public function addToCart() { //retrieve user data from session //retrieve product from database //add product information to quote //… //… //save quote data to database }
    6. 6. Domain ModelОбъектами представлены реальные сущности Business Logic Layer Category Product Order Quote Payment Cart Customer_Address Customer
    7. 7. Расслоение. А как в Magento?Sales Service Layer|--Block|--controllers Domain Models|--etc|--Helper Data Mappers|--Model| |--Mysql4 Data Access Objects| |-- Billing| |-- Entity| |-- Payment| |-- Order.php| |-- Quote.php
    8. 8. Mapping Objects to Data Source
    9. 9. Data Mapper/*Осуществляет передачу данных между объектами и базойданных, сохраняя их независимыми друг от друга и от самогомаппера*/
    10. 10. Zend Way<?phpclass App_Model_UserDataMapper{ public function save(App_Model_User $user) { Matthew $dao = $this->getDao(); Weier $id = $user->getId(); O’Phinney if (!$id) { $id = $dao->insert($user->toArray()); } else { $dao->update($user->toArray(), array(‘id=?’, $id)); } $record = $dao->find($id)->current(); $user->setOptions($record->toArray()); return $user; }
    11. 11. Вернемся к Magento Ресурс-моделиSales|--Block|--controllers <global> <models>|--etc <sales>|--Helper <class>Mage_Sales_Model</class> <resourceModel>sales_mysql4</resourceModel>|--Model </sales>| |--Mysql4 <sales_mysql4> <class>Mage_Sales_Model_Mysql4</class>| | |--Order.php <sales_mysql4>| | |--Quote.php <sales> <models>| |-- Billing <!-- ... -->| |-- Entity </global>| |-- Payment| |-- Order.php| |-- Quote.php Mage::getResourceModel(sales/order); ->load($order, $id, $field);
    12. 12. public function load(Mage_Core_Model_Abstract $object, $value, $field=null){ if (is_null($field)) { $field = $this->getIdFieldName(); Mage_Core_Model_Mysql4_Abstract } $read = $this->_getReadAdapter(); if ($read && !is_null($value)) { $select = $this->_getLoadSelect($field, $value, $object); $data = $read->fetchRow($select); if ($data) { $object->setData($data); } } $this->_afterLoad($object); return $this;}
    13. 13. Структура ресурс-модели Mage_Core_Model_Resource_Abstract #_getWriteAdapter() #_getWriteAdapter() #_getReadAdapter() #_getReadAdapter() + beginTrasnsaction() + beginTrasnsaction() Mage_Core_Model_Mysql4_Abstract Mage_Core_Model_Mysql4_Abstract + getMainTable() + getMainTable() + load() + save() + save() + delete() + delete() #_prepareDataForTable() #_prepareDataForTable()
    14. 14. Отличия от классикиДоменные модели знают о своих ресурс- моделях Mage_Sales_Model_Orderpublic function getProductIds(){ $ids = $this->getData(product_ids); if (is_null($ids)) { $ids = $this->_getResource()->getProductIds($this); $this->setProductIds($ids); } return $ids;}
    15. 15. Lazy and Eager Loading• Все данные есть под рукой • Может загрузить• Может потребоваться излишне много данныхслишком много обращенийк базе • Все данные есть под рукой
    16. 16. Lazy Loading in Magentopublic function getAddressesCollection() Mage_Sales_Model_Order{ if (is_null($this->_addresses)) { $this->_addresses = Mage::getResourceModel(sales/order_address_collection) ->setOrderFilter($this); if ($this->getId()) { foreach ($this->_addresses as $address) { $address->setOrder($this); } } } return $this->_addresses;}
    17. 17. Альтернативы. Table Data Gateway Name City Telephone Age Insurance Eugene Kyiv +3804456 21 32453453 Igor New York +45066 Model_DbTable 23452345 _Person +find() +findWithName() Model_Person +update() +insert()+getName() +delete()+getAddress()+sendEmail()+addFriend()+getFRiendSuggestions()
    18. 18. Альтернативы. Active Record Name City Telephone Age Insurance Eugene Kyiv +3804456 21 32453453 Igor New York +45066 Model_Person 23452345 +getName() +getAddress() +sendEmail() +addFriend() +getFriendSuggestions() +find() +findWithName() +update() +insert() +delete()
    19. 19. Коллекции. Identity MapgetElement(green) Identity Map find() empty load() Identity Map return( )
    20. 20. Magento Collections Ресурс-коллекцииSales|--Model| |--Mysql4| | |-- Collection| | | | -- Abstract.php Mage::getResourceModel(sales/order_collection)| | | -- Report ->addFieldToSelect(‘*‘)| | | | -- Collection.php ->setOrder(‘created_at‘, ‘desc);| | |--Order.php| | |--Quote.php| |-- Billing| |-- Entity $children = $this->getResourceCollection()| |-- Payment ->setOrderFilter($orderFilter)| |-- Order.php ->addPaymentIdFilter($paymentId)| |-- Quote.php ->addParentIdFilter($this->getId());
    21. 21. Структура коллекции Varien_Data_Collection Countable+getItemsByColumnValue()+addItem() IteratorAggregate+walk() Mage_Core_Model_Mysql4 Varien_Data_Collection_Db _Collection_Abstract+isLoaded() +addFiedToSelect()+load() +setModel()#_loadCache() +setResourceModel()#_saveCache() +save()
    22. 22. evgeniy.tulika@magento.com

    ×