Transparent Object Persistence (within FLOW3)
-
Upload
karsten-dambekalns -
Category
Technology
-
view
2.701 -
download
2
description
Transcript of Transparent Object Persistence (within FLOW3)
Inspiring people toshare
Transparent Object Persistence
(within FLOW3)Karsten Dambekalns <[email protected]>
Samstag, 16. Mai 2009
Inspiring people toshare
“DDD persistence”Domain Models encapsulate behavior and data
Concerned about the problem – only
Infrastructure is of no relevance
Unfortunately you need to be aware of the infrastructure at some point – at least a little
Samstag, 16. Mai 2009
Inspiring people toshare
EntitiesIdentity is important
Are not defined by their attributes
Examples could be...
• Projects
• Developers
Samstag, 16. Mai 2009
Inspiring people toshare
Value objectsHave no indentity
Their value is of importance
Are interchangeable
Examples could be...
• Colors
• Numbers
• Tags in Forge
Samstag, 16. Mai 2009
Inspiring people toshare
AggregatesCluster associated objects
Have a boundary and a root
The root is a specific entity
References from outside point to the root
An example for an aggregate:
• Project
Samstag, 16. Mai 2009
Inspiring people toshare
RepositoriesProvide access to entities (and aggregates)
Allow to find a starting point for traversal
Persisted objects can be searched for
Queries can be built in various ways
Handle storage of additions and updates
Samstag, 16. Mai 2009
Inspiring people toshare
A Domain ModelProject
Repository
Project
twitter Account
Developer
SVN Account
Samstag, 16. Mai 2009
Inspiring people toshare
A Domain ModelProject
Repository
Project
twitter Account
Developer
SVN Account
Reposit
Samstag, 16. Mai 2009
Inspiring people toshare
A Domain ModelProject
Repository
Project
twitter Account
Developer
SVN Account
Reposit
Samstag, 16. Mai 2009
Inspiring people toshare
A Domain ModelProject
Repository
Project
twitter Account
Developer
SVN Account
Reposit
Samstag, 16. Mai 2009
Inspiring people toshare
A Domain ModelProject
Repository
Project
twitter Account
Developer
SVN Account
Reposit
Aggre-gates
Samstag, 16. Mai 2009
Inspiring people toshare
A Domain Model
twitter Account
Developer
SVN Account
Samstag, 16. Mai 2009
Inspiring people toshare
Using FLOW3...You just implement the model
No need to care about persisting your model
FLOW3 handles this for you – transparently
Even a Repository only needs little work
Define relevant metadata in the source file using annotations
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used@entity
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used@entity
@valueobject
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used@entity
@valueobject
@var
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used@entity
@valueobject
@var
@transient
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used@entity
@valueobject
@var
@transient
@uuid
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used@entity
@valueobject
@var
@transient
@uuid
@identity
Samstag, 16. Mai 2009
Inspiring people toshare
@nnotations used@entity
@valueobject
@var
@transient
@uuid
@identity
@lazy
Samstag, 16. Mai 2009
Inspiring people toshare
Persistence ManagerMostly invisible to developers
Manages additions of and updates to objects
Concerned only about objects in repositories
Collects objects and hands over to backend
Allows for objects being persisted at any time
Automatically called to persist at end of script run
Samstag, 16. Mai 2009
Inspiring people toshare
Simplified stack
SQLite PgSQL MySQL ...
Samstag, 16. Mai 2009
Inspiring people toshare
Simplified stack
SQLite PgSQL MySQL ...
PDO ...
Samstag, 16. Mai 2009
Inspiring people toshare
Simplified stack
SQLite PgSQL MySQL ...
TYPO3 Content Repository
PDO ...
Samstag, 16. Mai 2009
Inspiring people toshare
Simplified stack
SQLite PgSQL MySQL ...
TYPO3 Content Repository
PDO ...
FLOW3 Persistence
Samstag, 16. Mai 2009
Inspiring people toshare
Simplified stack
SQLite PgSQL MySQL ...
TYPO3 Content Repository
PDO ...
FLOW3 Persistence
Application Application
Samstag, 16. Mai 2009
Inspiring people toshare
Simplified stack
TYPO3 CR
FLOW3 Persistence
Persistence Backend
Samstag, 16. Mai 2009
Inspiring people toshare
FLOW3TYPO3 CR
Samstag, 16. Mai 2009
Inspiring people toshare
Transparent persistenceExplicit support for Domain-Driven Design
Class Schemata are defined by the Domain Model class
• No need to write an XML or YAML schema definition
• No need to define the database model and object model multiple times at different places
Automatic persistence in the JSR-283 based Content Repository
Legacy data sources can be mounted
Samstag, 16. Mai 2009
Inspiring people toshare
Query FactoryCreates a query for you
Decouples persistence layer from backend
Must be implemented by backend
API with one method:
• public function create($className);
Samstag, 16. Mai 2009
Inspiring people toshare
Query objectsRepresent a query for an object type
Allow criteria to be attached
Must be implemented by backend
Simple API
• execute()
• matching()
• equals(), lessThan(), ...
• ...
Samstag, 16. Mai 2009
Inspiring people toshare
Object reconstitutionWhen fetching objects the content repository looks for matching nodes
The nodes are mapped to objects by a data mapper
Reconstitution
• does not call __construct()
• restores all non-transient properties
• reinjects dependencies (skips constructor arguments)
Samstag, 16. Mai 2009
Inspiring people toshare
public function map(\F3\PHPCR\NodeIteratorInterface $nodes) { $objects = array(); foreach ($nodes as $node) { $object = $this->mapSingleNode($node); $this->persistenceManager->getSession()->registerReconstitutedObject($object); $objects[] = $object; }
return $objects;}
Object reconstitution
\F3\TYPO3CR\FLOW3\Persistence\DataMapper
Samstag, 16. Mai 2009
Inspiring people toshare
$explodedNodeTypeName = explode(':', $node->getPrimaryNodeType()->getName(), 2);$className = str_replace('_', '\\', $explodedNodeTypeName[1]);$classSchema = $this->persistenceManager->getClassSchema($className);$objectConfiguration = $this->objectManager->getObjectConfiguration($className);
$object = $this->objectBuilder->createEmptyObject($className, $objectConfiguration);$this->identityMap->registerObject($object, $node->getIdentifier());
$this->objectBuilder->reinjectDependencies($object, $objectConfiguration);$this->thawProperties($object, $node, $classSchema);$object->FLOW3_Persistence_memorizeCleanState();
Object reconstitution
\F3\TYPO3CR\FLOW3\Persistence\DataMapper
Samstag, 16. Mai 2009
Inspiring people toshare
public function createEmptyObject($objectName, \F3\FLOW3\Object\Configuration $objectConfiguration) {
$className = $objectConfiguration->getClassName();
if (!in_array('F3\FLOW3\AOP\ProxyInterface', class_implements($className))) {throw new \F3\FLOW3\Object\Exception\CannotReconstituteObject('Cannot create empty instance of the class "' . $className . '" because it does not implement the AOP Proxy Interface.', 1234386924);
}
$object = unserialize('O:' . strlen($className) . ':"' . $className . '":0:{};'); $object->FLOW3_AOP_Proxy_setProperty('objectFactory', $this->objectFactory); $object->FLOW3_AOP_Proxy_setProperty('objectManager', $this->objectManager); $object->FLOW3_AOP_Proxy_declareMethodsAndAdvices();
return $object;}
Object reconstitution
\F3\FLOW3\Object\Builder
Samstag, 16. Mai 2009
Inspiring people toshare
Lazy LoadingLoading a full object tree makes sense – or not
It does most of the time
If your domain model has small aggregates eager loading makes sense
If you have expensive to create objects or a lot of smaller ones you don’t always need, lazy loading helps
Example: displaying a list of projects doesn’t need the projects details, just the names
Samstag, 16. Mai 2009
Inspiring people toshare
Lazy LoadingIdeally you would not think about lazy loading beyond the addition of the @lazy annotation
In practice you need to be aware of some technical issues
In place of the real object you get a proxy, so
• you can’t use it at type hinted places
• pass it around without some thinking
Using it otherwise works as expected
After first use the proxy will be completely gone
Samstag, 16. Mai 2009
Inspiring people toshare
public function _loadRealInstance() { $realInstance = $this
->F3_FLOW3_Persistence_LazyLoadingProxy_population->__invoke();
$this->F3_FLOW3_Persistence_LazyLoadingProxy_parent->FLOW3_AOP_Proxy_setProperty(
$this->F3_FLOW3_Persistence_LazyLoadingProxy_propertyName, $realInstance
);
return $realInstance;}
The LazyLoadingProxy
\F3\FLOW3\Persistence\LazyLoadingProxy
Samstag, 16. Mai 2009
Inspiring people toshare
$dataMapper = $this; // make available to closure...$objectStorage = new \F3\FLOW3\Persistence\LazyLoadingProxy( $parent, $propertyName, function() use ($proxyNode, $dataMapper) { $objectStorage = new \SplObjectStorage(); $itemNodes = $proxyNode->getNodes(); foreach ($itemNodes as $itemNode) { $objectNode = $itemNode->getNode('flow3:object'); if ($objectNode->getPrimaryNodeType()->getName() ===
\F3\TYPO3CR\FLOW3\Persistence\Backend::NODETYPE_OBJECTPROXY) { $object = $dataMapper->mapObjectProxyNode($objectNode); } else { $object = $dataMapper->mapSingleNode($objectNode); } $objectStorage->attach($object); } return $objectStorage; });
\F3\TYPO3CR\FLOW3\Persistence\DataMapper
Samstag, 16. Mai 2009
Inspiring people toshare
Node structurePHP has more data structures than a content repository, e.g.
• JSR-283 defines multi-valued properties without keys and without stable ordering
• Arrays in PHP have keys and order that are stable and might be important for your code
Thus we do some more mapping to node structures
Samstag, 16. Mai 2009
Inspiring people toshare
Samstag, 16. Mai 2009
Inspiring people toshare
Samstag, 16. Mai 2009
Inspiring people toshare
Samstag, 16. Mai 2009
Inspiring people toshare
Samstag, 16. Mai 2009
Inspiring people toshare
Samstag, 16. Mai 2009
Inspiring people toshare
Questions!
Samstag, 16. Mai 2009
Inspiring people toshare
Samstag, 16. Mai 2009
Inspiring people toshare
LinksFLOW3http://flow3.typo3.org/
TYPO3CRhttp://forge.typo3.org/projects/show/package-typo3cr
JSR-283http://jcp.org/en/jsr/detail?id=283
Samstag, 16. Mai 2009
Samstag, 16. Mai 2009
Inspiring people toshare
Flickr photo credits:megapixel13 (barcode), rmrayner (ring), Ducatirider (grapes), Here’s Kate (book shelf)Pumpkin pictures:http://ptnoticias.com/pumpkinway/
Samstag, 16. Mai 2009