+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
Transparent Object Persistence (within FLOW3)
1. Transparent Object
Persistence
(within FLOW3)
Karsten Dambekalns <karsten@typo3.org>
Inspiring people to
share
Samstag, 16. Mai 2009
2. “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
Inspiring people to
share
Samstag, 16. Mai 2009
3. Entities
Identity is important
Are not defined by their attributes
Examples could be...
• Projects
• Developers
Inspiring people to
share
Samstag, 16. Mai 2009
4. Value objects
Have no indentity
Their value is of importance
Are interchangeable
Examples could be...
• Colors
• Numbers
• Tags in Forge
Inspiring people to
share
Samstag, 16. Mai 2009
5. Aggregates
Cluster 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
Inspiring people to
share
Samstag, 16. Mai 2009
6. Repositories
Provide 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
Inspiring people to
share
Samstag, 16. Mai 2009
7. A Domain Model
Project
Repository
Project
Developer
SVN twitter
Account Account
Inspiring people to
share
Samstag, 16. Mai 2009
8. A Domain Model
Project
Repository
it
Project
Repos
Developer
SVN twitter
Account Account
Inspiring people to
share
Samstag, 16. Mai 2009
9. A Domain Model
Project
Repository
it
Project
Repos
Developer
SVN twitter
Account Account
Inspiring people to
share
Samstag, 16. Mai 2009
10. A Domain Model
Project
Repository
it
Project
Repos
Developer
SVN twitter
Account Account
Inspiring people to
share
Samstag, 16. Mai 2009
11. A Domain Model
Project
Repository
it
Project
Repos
Developer
Aggre-
gates SVN twitter
Account Account
Inspiring people to
share
Samstag, 16. Mai 2009
12. A Domain Model
Developer
SVN twitter
Account Account
Inspiring people to
share
Samstag, 16. Mai 2009
13. 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
Inspiring people to
share
Samstag, 16. Mai 2009
14. @nnotations used
Inspiring people to
share
Samstag, 16. Mai 2009
15. @nnotations used
@entity
Inspiring people to
share
Samstag, 16. Mai 2009
16. @nnotations used
@entity
@valueobject
Inspiring people to
share
Samstag, 16. Mai 2009
17. @nnotations used
@entity
@valueobject
@var
Inspiring people to
share
Samstag, 16. Mai 2009
18. @nnotations used
@entity
@valueobject
@var
@transient
Inspiring people to
share
Samstag, 16. Mai 2009
19. @nnotations used
@entity
@valueobject
@var
@transient
@uuid
Inspiring people to
share
Samstag, 16. Mai 2009
20. @nnotations used
@entity
@valueobject
@var
@transient
@uuid
@identity
Inspiring people to
share
Samstag, 16. Mai 2009
21. @nnotations used
@entity
@valueobject
@var
@transient
@uuid
@identity
@lazy
Inspiring people to
share
Samstag, 16. Mai 2009
22. Persistence Manager
Mostly 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
Inspiring people to
share
Samstag, 16. Mai 2009
23. Simplified stack
SQLite PgSQL MySQL ...
Inspiring people to
share
Samstag, 16. Mai 2009
24. Simplified stack
PDO ...
SQLite PgSQL MySQL ...
Inspiring people to
share
Samstag, 16. Mai 2009
25. Simplified stack
TYPO3 Content Repository
PDO ...
SQLite PgSQL MySQL ...
Inspiring people to
share
Samstag, 16. Mai 2009
26. Simplified stack
FLOW3 Persistence
TYPO3 Content Repository
PDO ...
SQLite PgSQL MySQL ...
Inspiring people to
share
Samstag, 16. Mai 2009
27. Simplified stack
Application Application
FLOW3 Persistence
TYPO3 Content Repository
PDO ...
SQLite PgSQL MySQL ...
Inspiring people to
share
Samstag, 16. Mai 2009
28. Simplified stack
FLOW3 Persistence
Persistence
TYPO3 CR
Backend
Inspiring people to
share
Samstag, 16. Mai 2009
29. TYPO3 CR
FLOW3
Inspiring people to
share
Samstag, 16. Mai 2009
30. Transparent persistence
Explicit 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
Inspiring people to
share
Samstag, 16. Mai 2009
31. Query Factory
Creates a query for you
Decouples persistence layer from backend
Must be implemented by backend
API with one method:
• public function create($className);
Inspiring people to
share
Samstag, 16. Mai 2009
32. Query objects
Represent a query for an object type
Allow criteria to be attached
Must be implemented by backend
Simple API
• execute()
• matching()
• equals(), lessThan(), ...
• ...
Inspiring people to
share
Samstag, 16. Mai 2009
33. Object reconstitution
When 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)
Inspiring people to
share
Samstag, 16. Mai 2009
34. Object reconstitution
public function map(F3PHPCRNodeIteratorInterface $nodes) {
$objects = array();
foreach ($nodes as $node) {
$object = $this->mapSingleNode($node);
$this->persistenceManager->getSession()->registerReconstitutedObject($object);
$objects[] = $object;
}
return $objects;
}
F3TYPO3CRFLOW3PersistenceDataMapper
Inspiring people to
share
Samstag, 16. Mai 2009
36. Object reconstitution
public function createEmptyObject($objectName, F3FLOW3ObjectConfiguration
$objectConfiguration) {
$className = $objectConfiguration->getClassName();
if (!in_array('F3FLOW3AOPProxyInterface', class_implements($className))) {
throw new F3FLOW3ObjectExceptionCannotReconstituteObject('Cannot create
empty instance of the class quot;' . $className . 'quot; because it does not implement
the AOP Proxy Interface.', 1234386924);
}
$object = unserialize('O:' . strlen($className) . ':quot;' . $className . 'quot;:0:{};');
$object->FLOW3_AOP_Proxy_setProperty('objectFactory', $this->objectFactory);
$object->FLOW3_AOP_Proxy_setProperty('objectManager', $this->objectManager);
$object->FLOW3_AOP_Proxy_declareMethodsAndAdvices();
return $object;
}
F3FLOW3ObjectBuilder
Inspiring people to
share
Samstag, 16. Mai 2009
37. Lazy Loading
Loading 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
Inspiring people to
share
Samstag, 16. Mai 2009
38. Lazy Loading
Ideally 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
Inspiring people to
share
Samstag, 16. Mai 2009
39. The LazyLoadingProxy
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;
}
F3FLOW3PersistenceLazyLoadingProxy
Inspiring people to
share
Samstag, 16. Mai 2009
40. $dataMapper = $this; // make available to closure...
$objectStorage = new F3FLOW3PersistenceLazyLoadingProxy(
$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() ===
F3TYPO3CRFLOW3PersistenceBackend::NODETYPE_OBJECTPROXY) {
$object = $dataMapper->mapObjectProxyNode($objectNode);
} else {
$object = $dataMapper->mapSingleNode($objectNode);
}
$objectStorage->attach($object);
}
return $objectStorage;
}
);
F3TYPO3CRFLOW3PersistenceDataMapper
Inspiring people to
share
Samstag, 16. Mai 2009
41. Node structure
PHP 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
Inspiring people to
share
Samstag, 16. Mai 2009