Transparent Object Persistence (within FLOW3)

51
Inspiring people to share Transparent Object Persistence (within FLOW3) Karsten Dambekalns <[email protected]> Samstag, 16. Mai 2009

description

An overview and some details about how object persistence in FLOW3 works internally.

Transcript of Transparent Object Persistence (within FLOW3)

Page 1: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Transparent Object Persistence

(within FLOW3)Karsten Dambekalns <[email protected]>

Samstag, 16. Mai 2009

Page 2: Transparent Object Persistence (within FLOW3)

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

Page 3: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

EntitiesIdentity is important

Are not defined by their attributes

Examples could be...

• Projects

• Developers

Samstag, 16. Mai 2009

Page 4: Transparent Object Persistence (within FLOW3)

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

Page 5: Transparent Object Persistence (within FLOW3)

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

Page 6: Transparent Object Persistence (within FLOW3)

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

Page 7: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

A Domain ModelProject

Repository

Project

twitter Account

Developer

SVN Account

Samstag, 16. Mai 2009

Page 8: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

A Domain ModelProject

Repository

Project

twitter Account

Developer

SVN Account

Reposit

Samstag, 16. Mai 2009

Page 9: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

A Domain ModelProject

Repository

Project

twitter Account

Developer

SVN Account

Reposit

Samstag, 16. Mai 2009

Page 10: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

A Domain ModelProject

Repository

Project

twitter Account

Developer

SVN Account

Reposit

Samstag, 16. Mai 2009

Page 11: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

A Domain ModelProject

Repository

Project

twitter Account

Developer

SVN Account

Reposit

Aggre-gates

Samstag, 16. Mai 2009

Page 12: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

A Domain Model

twitter Account

Developer

SVN Account

Samstag, 16. Mai 2009

Page 13: Transparent Object Persistence (within FLOW3)

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

Page 14: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used

Samstag, 16. Mai 2009

Page 15: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used@entity

Samstag, 16. Mai 2009

Page 16: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used@entity

@valueobject

Samstag, 16. Mai 2009

Page 17: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used@entity

@valueobject

@var

Samstag, 16. Mai 2009

Page 18: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used@entity

@valueobject

@var

@transient

Samstag, 16. Mai 2009

Page 19: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used@entity

@valueobject

@var

@transient

@uuid

Samstag, 16. Mai 2009

Page 20: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used@entity

@valueobject

@var

@transient

@uuid

@identity

Samstag, 16. Mai 2009

Page 21: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

@nnotations used@entity

@valueobject

@var

@transient

@uuid

@identity

@lazy

Samstag, 16. Mai 2009

Page 22: Transparent Object Persistence (within FLOW3)

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

Page 23: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Simplified stack

SQLite PgSQL MySQL ...

Samstag, 16. Mai 2009

Page 24: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Simplified stack

SQLite PgSQL MySQL ...

PDO ...

Samstag, 16. Mai 2009

Page 25: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Simplified stack

SQLite PgSQL MySQL ...

TYPO3 Content Repository

PDO ...

Samstag, 16. Mai 2009

Page 26: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Simplified stack

SQLite PgSQL MySQL ...

TYPO3 Content Repository

PDO ...

FLOW3 Persistence

Samstag, 16. Mai 2009

Page 27: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Simplified stack

SQLite PgSQL MySQL ...

TYPO3 Content Repository

PDO ...

FLOW3 Persistence

Application Application

Samstag, 16. Mai 2009

Page 28: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Simplified stack

TYPO3 CR

FLOW3 Persistence

Persistence Backend

Samstag, 16. Mai 2009

Page 29: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

FLOW3TYPO3 CR

Samstag, 16. Mai 2009

Page 30: Transparent Object Persistence (within FLOW3)

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

Page 31: Transparent Object Persistence (within FLOW3)

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

Page 32: Transparent Object Persistence (within FLOW3)

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

Page 33: Transparent Object Persistence (within FLOW3)

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

Page 34: Transparent Object Persistence (within FLOW3)

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

Page 35: Transparent Object Persistence (within FLOW3)

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

Page 36: Transparent Object Persistence (within FLOW3)

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

Page 37: Transparent Object Persistence (within FLOW3)

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

Page 38: Transparent Object Persistence (within FLOW3)

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

Page 39: Transparent Object Persistence (within FLOW3)

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

Page 40: Transparent Object Persistence (within FLOW3)

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

Page 41: Transparent Object Persistence (within FLOW3)

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

Page 42: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Samstag, 16. Mai 2009

Page 43: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Samstag, 16. Mai 2009

Page 44: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Samstag, 16. Mai 2009

Page 45: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Samstag, 16. Mai 2009

Page 46: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Samstag, 16. Mai 2009

Page 47: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Questions!

Samstag, 16. Mai 2009

Page 48: Transparent Object Persistence (within FLOW3)

Inspiring people toshare

Samstag, 16. Mai 2009

Page 49: Transparent Object Persistence (within FLOW3)

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

Page 50: Transparent Object Persistence (within FLOW3)

Samstag, 16. Mai 2009

Page 51: Transparent Object Persistence (within FLOW3)

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