MVC – Model Lessons learned

Download Report

Transcript MVC – Model Lessons learned

Click to edit Master title style
Ibiza, June 4th – 7th 2011
Application Models Design
Lessons Learned in Magento Models
by Anton Makarenko, PHP-Developer at Magento 2
Research
Goals:
• Better maintainable model layer, less code
coupling
• Better solution for multiple RDBMSs support
Application Models Design
1.
2.
3.
4.
5.
Domain and Service Layers
Models Design in Magento
Collections Design in Magento
Entities and Service Layer in Doctrine ORM
Possible Solution for Magento
Application Models Design
Theoretical Background
1. DOMAIN AND SERVICE LAYERS
Decomposing Model Layer by Role
• Domain model – an entity or business rule
implementation
• Service model – application logic:
instantiation, composition, collections
and data delivery
Entity (Domain Model)
• Represents a “real-world” entity
• Defines data fields and a way to identify
an entity
• Protects data integrity
• Implements domain behavior
Service Model Layer
• Implements arbitrary application logic
• Arbitrary hierarchy of models for:
– Data mapping
– Composition of models, domains
– Utility purposes
Criteria for Creating Hierarchy of Models
• Complexity of task
• Necessity for different use cases
• Requirements for application flexibility
Model Hierarchy Detalization
Toy
Car
Vehicle
Wheel
Car
Truck
Driver’s Seat
Frame
Data Sharing Between Models
Entities
Application
Framework
Customer
Entity
Manager
Database
access
Configuration
Caching
Quote
Product
Data Sharing Between Models
Horizontal Exchange
Vertical Exchange
• One namespace between
“neighbors”
• Allow dependencies
on the same level
• Different namespaces =
mapping between models
of different hierarchy
levels
• Strive to loose
dependencies
Data Encapsulation in Models
Entity Model
Service Model
• Enforce all required
and valid data
in constructor and setters
• Allow to inject data only
through strict interface
• Stateless or with
predictable state
• Laconic public interface
Application Models Design
2. MODELS DESIGN IN MAGENTO
Backwards Compatibility
What are Models in Magento?
Models
• “Business
logic”
• Entities
Resource
Models
• Entity
persistence
• Data
manipulation,
indexing
Collections
• Reading sets
of data
• Reports
What are Models in Magento?
Mage::getModel()
• Standalone domain models
• Entity domain models (Mage_Core_Model_Abstract)
Mage::getResourceModel()
• Resource models (Mage_Core_Model_Resource_Abstract) – service layer
• Collections (Varien_Data_Collection_Db) – also service layer
Mage::helper()
• Helpers (Mage_Core_Helper_Abstract) – a bit of service layer as well
Super Models
Super Models in Magento
Reuse Through Inheritance
• Constrains designing
classes hierarchy
• No natural “is-a” relation
• Fails attempt to reuse
code by bloating interface
Reuse Through Composition
• Real “is-a” relations,
polymorphism
• Less coupling, more
freedom in designing
classes
• More scalable and more
expensive in terms
of number of objects
in memory
Backwards Compatibility
Mage_Core_Model_Abstract
Service Interface
•
•
•
•
•
•
•
•
save()
load()
delete()
getResource()
getCollection()
afterLoad()
afterCommitCallback()
isObjectNew()
Entity (Domain) Interface
• N/A
Varien_Object
Data Object
• __call()
• getData()
• setData()
• unsetData()
• hasData()
•Irrelevant
Cons Features
• Entity:
• Get/Set ID
• ID field name
• Service:
• Get/Set origData
• hasDataChanges()
Mage_Core_Model_Resource_Db_Abstract
Methods
Purpose
save(), load(), delete()
Entity CRUD
getIdFieldName(), hasDataChanged()
Relation with “abstract model”
afterLoad()
Hook for collections
getTable(), getMainTable(),
getReadConnection()
Provide direct DB access to resource
collections
_prepareDataForTable(), _checkUnique()
Dynamic analysis of table structure
on entity “save” operation
Entity and Resource Models Summary
• Dynamic entity structure:
– Domain structural inconsistency
– DB DDL overhead
• Scattered service logic
– Contaminated entity models
– Code encapsulation challenge
– Exposure of DB layer
Backwards Compatibility
Application Models Design
3. COLLECTIONS DESIGN IN MAGENTO
The Real Purpose of Collections
Collection “Natural” Purpose
Collection in Magento
• To enforce data of certain
type
• Iterating capability
• The “Lazy-Load” pattern
triggered by iteration
• Enforce type – Yes
• Iterate & Lazy-load – Yes
• Data set formalization:
– fields, filters, limitation,
sorting
• Part of service layer:
– Deals with database
– Instantiates objects
Components that Depend on Collections
•
•
•
•
Domain models
Service layer
Controllers and view (templates)
Special case – (admin) grids
Collections Hierarchy
Varien_Data_Collection
Varien_Db_Adapter_*
Varien_Data_Collection_Db
Mage_Core_Model_Resource
_Abstract
Mage_Core_Model_Resource
_Db_Collection_Abstract
Mage_Core_Model_Resource
_Db_Abstract
Mage_Core_Model_Resource
Mage_Cms_Model_Resource
_Page_Collection
Mage_Cms_Model_Resource
_Page
Collections as Resources
• Duplication of resource layer logic
• Necessity to break encapsulation
• Necessity to implement collection class
for each entity
Backwards Compatibility
The Triangle
Collections
3x ~200
Domain
Entities
Resource
Layer
Application Models Design
4. ENTITIES AND SERVICE LAYER
IN DOCTRINE ORM
What is ORM
Magento
Doctrine
ORM 2.x
How Doctrine ORM Works
Product
Customer
Controller, View…
Order
Other Domain
and Service Models
Entities
XML, YAML,
PHPDoc
Entity Manager
Doctrine ORM
DB
Can Doctrine ORM Be Adopted in Magento?
• A ready solution for domain and service
layers
• Entities – a best practice implementation
• Entity manager and data persistence
• Collections
• Database abstraction layer (DBAL)
Doctrine ORM Can’t Be Adopted in Magento
• Migration efforts to DBAL
• Potential performance issues:
– There are up to 30 classes loaded to instantiate
an entity
– Objects initialization through unserialize() –
possible performance bottleneck
Future Compatibility with Doctrine ORM
• Entity fields to be declared as class
attributes
• One or more entity fields to serve
as identity key
Application Models Design
Magento 2
5. POSSIBLE SOLUTION
FOR MAGENTO
Implementing Entities
• Move out service layer logic from domain
models:
– No persistence handling
– No cascade handling of other entities
• Enforce domain model consistency using
strict constructor, type hinting
in setters and declared fields
OrigData Use Cases
• getOrigData($key)
– track changes “before save” (service layer)
• getOrigData()
– log object changes (Enterprise_Logging)
• hasDataChanges()
– rare specific cases in different places (service,
controllers)
Memento Pattern for Entities Data
Implementing Service Layer
• Entity managers: generic for primitive
entities, custom for complex entities
• Data (database) access inside entity
manager = disband resource models
• Implement data set handling in entity
managers (ex-collections territory)
New Entity Manager Responsibilities
• Deal with DB access layer directly
• CRUD operations
• Get collection data from DB
Service Layer and Multiple RDBMSs
Zend_Db_Adapter_Abstract
Zend_Db_Adapter_Pdo_Mysql
Varien_Db_Adapter_Pdo_Mysql
Service Layer and Multiple RDBMSs
Zend_Db_Adapter_Abstract
Zend_*_Pdo_Mssql
Zend_Db_Adapter_Pdo_Mysql
Zend_*_Oracle
Varien_*_Pdo_Mssql
Varien_Db_Adapter_Pdo_Mysql
Varien_*_Oracle
Service Layer and Multiple RDBMSs
Service Layer and Application Resources
Slightly reduced collections responsibility:
• No more DB layer access
• No more objects instantiation
• Data set formalization delegated
to separate utility class
~200
1
Making it Work Together
Summary, Q & A
• Better maneuver space for domain models
• DB abstraction layer improved for better
multiple RDBMSs support
• Lightweight service layer
Thank you!