Your SlideShare is downloading. ×
Transparent Object Persistence with FLOW3
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Transparent Object Persistence with FLOW3

3,766

Published on

Introduction to the persistent layer implemented for FLOW3. The presentation was held on the 4th International TYPO3 Conference in Berlin, October 2008.

Introduction to the persistent layer implemented for FLOW3. The presentation was held on the 4th International TYPO3 Conference in Berlin, October 2008.

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
3,766
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
42
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Transparent Object Persistence (with FLOW3) Karsten Dambekalns <karsten@typo3.org> Inspiring people to share
  • 2. Old school persistence DDD persistence FLOW3 persistence Inspiring people to share
  • 3. An example to use... Let’s use a Blog A Blog projects has • a Blog • some Posts, • Comments and • Tags Easy enough, eh? Inspiring people to share
  • 4. Setting the stage A blog is requested We want to show posts We have data somewhere We use MVC and have a view waiting We only need to hand over the posts Inspiring people to share
  • 5. Blog tables^Wrelations blogs uid name 1 FLOW3 posts uid blog_id title author text date 1 1 FLOW3 R. Lemke M!s esam vissforšquot;kie, tquot;p!c ka... 2008-10-07 comments uid post_id author text 1 1 Kasper Skårhøj Nice writeup, but... posts_tags tags post_id tag_id uid name 1 1 1 PHP 1 3 2 DDD 3 FLOW3
  • 6. Straight DB usage $row = mysql_fetch_assoc( mysql_query('SELECT uid FROM blogs WHERE name = '' . mysql_real_escape_string($blog) . ''') ); $blogId = $row['uid']; $posts = array(); $res = mysql_query('SELECT * FROM posts WHERE blog_id = ' . $blogId); while (($row = mysql_fetch_assoc($res)) !== FALSE) { $posts[] = $row; } $view->setPosts($posts); Inspiring people to share
  • 7. Straight DB usage $row = mysql_fetch_assoc( mysql_query('SELECT uid FROM blogs WHERE name = '' . mysql_real_escape_string($blog) . ''') ); $blogId = $row['uid']; $posts = array(); SQL injection! • $res = mysql_query('SELECT * FROM posts WHERE blog_id = ' . $blogId); while (($row = mysql_fetch_assoc($res)) !== FALSE) { $posts[] = $row; •clumsy code } •other RDBMS $view->setPosts($posts); •field changes? Inspiring people to share
  • 8. DBAL in TYPO3v4 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', 'blogs', 'name = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($blog, 'blogs')); $blogId = $rows[0]['uid']; $posts = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'posts', 'blog_id = ' . $blogId); $view->setPosts($posts); Inspiring people to share
  • 9. DBAL in TYPO3v4 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', 'blogs', 'name = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($blog, 'blogs')); $blogId = $rows[0]['uid']; $posts = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'posts', 'blog_id = ' . $blogId); $view->setPosts($posts); SQL injection! • •still clumsy... •field changes? Inspiring people to share
  • 10. ORM tools ORM means Object-Relational Mapping Objects represent a database row Most tools are rather ROM – still focus on relational thinking Implementations differ • ORM base classes need to be extended • Schema is used to generate code Inspiring people to share
  • 11. Active Record $blog = new Blog($blog); $posts = $blog->getPosts(); $view->setPosts($posts); •very nice •dependency on ORM tool? •save()/delete( ) Inspiring people to share
  • 12. Active Record $blog = new Blog($blog); $posts = $blog->getPosts(); $view->setPosts($posts); •very nice •dependency on $post->save(); $post->delete(); ORM tool? •save()/delete( ) Inspiring people to share
  • 13. “DDD persistence” Domain Models encapsulate behavior and data Concerned about the problem – only Infrastructure is of no relevance Inspiring people to share
  • 14. Entities Identity is important Are not defined by their attributes Examples could be... • People • Blog posts Inspiring people to share
  • 15. Value objects Have no indentity Their value is of importance Are interchangeable Examples could be... • Colors • Numbers • Tags in a blog Inspiring people to share
  • 16. Aggregates Cluster associated objects Have a boundary and a root The root is a specific entity References from outside point to the root Inspiring people to share
  • 17. Repositories Provide access to aggregates and entities Allow to find a starting point for traversal Persistent objects can be searched for Queries can be built in various ways Handle storage of additions and updates Inspiring people to share
  • 18. A Domain Model Blog Repository Blog Post Comment Tag Inspiring people to share
  • 19. A Domain Model Blog Repository it Blog Repos Post Comment Tag Inspiring people to share
  • 20. A Domain Model Blog Repository it Blog Repos Post Comment Tag Inspiring people to share
  • 21. A Domain Model Blog Repository it Blog Repos Post Comment Tag Inspiring people to share
  • 22. A Domain Model Blog Repository it Blog Repos Post Aggre! gates Comment Tag Inspiring people to share
  • 23. A Domain Model Post Comment Tag Inspiring people to share
  • 24. A Domain Model Post Entity Comment Tag Entity Inspiring people to share
  • 25. A Domain Model Post Entity Val Comment Tag ue Entity Inspiring people to share
  • 26. Implementing this... must be a lot of work! Inspiring people to share
  • 27. Using FLOW3? Inspiring people to share
  • 28. Using FLOW3? Inspiring people to share
  • 29. 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 Inspiring people to share
  • 30. The Blog class class Blog { /** * @var string */ protected $name; /** * @var array * @reference */ protected $posts = array(); /** * Constructs this blog * * @param string $name Name of this blog * @return */ public function __construct($name) { $this->name = $name; } Inspiring people to share
  • 31. The Blog class /** * Adds a post to this blog * * @param F3::Blog::Domain::Post $post * @return void * @author Karsten Dambekalns <karsten@typo3.org> */ public function addPost(F3::Blog::Domain::Post $post) { $this->posts[] = $post; } /** * Returns all posts in this blog * * @return array of F3::Blog::Domain::Post * @author Karsten Dambekalns <karsten@typo3.org> */ public function getPosts() { return $this->posts; } Inspiring people to share
  • 32. The Blog class /** * Returns the latest $count posts from the blog * * @param integer $count * @return array of F3::Blog::Domain::Post * @author Karsten Dambekalns <karsten@typo3.org> */ public function getLatestPosts($count = 5) { return array_slice($this->posts, -$count, $count, TRUE); } /** * Returns posts posts by tag * * @param string $tag * @return array of F3::Blog::Domain::Post * @author Bastian Waidelich <bastian@typo3.org> */ public function findPostsByTag($tag) { ... Inspiring people to share
  • 33. The Post class class Post { /** * @var string UUID * @identifier */ protected $identifier; /** * @var string */ protected $title; /** * @var array * @reference */ protected $tags = array(); Inspiring people to share
  • 34. The Post class /** * Constructs this post * * @author Robert Lemke <robert@typo3.org> * @author Bastian Waidelich <bastian@typo3.org> */ public function __construct() { $this->date = new DateTime(); $this->identifier = F3::FLOW3::Utility::Algorithms::generateUUID(); } /** * Adds a comment to this post * * @param F3::Blog::Domain::Comment $comment * @return void * @author Robert Lemke <robert@typo3.org> */ public function addComment(F3::Blog::Domain::Comment $comment) { $this->comments[] = $comment; } Inspiring people to share
  • 35. The Comment class class Comment { /** * @var string */ protected $author; /** * @var string */ protected $content; /** * Constructs this comment * * @author Karsten Dambekalns <karsten@typo3.org> */ public function __construct() { $this->date = new DateTime(); } Inspiring people to share
  • 36. The Tag class class Tag { /** * @var string */ protected $name; /** * Setter for name * * @param string $name * @return void * @author Karsten Dambekalns <karsten@typo3.org> */ public function setName($name) { $this->name = $name; } } Inspiring people to share
  • 37. The BlogRepository Now this really must be a complex piece of code, no? One word: No Inspiring people to share
  • 38. The BlogRepository Now this really must be a complex piece of code, no? One word: No class BlogRepository extends F3::FLOW3::Persistence::Repository { /** * Returns one or more Blogs with a matching name if found. * * @param string $name The name to match against * @return array */ public function findByName($name) { $query = $this->createQuery(); $blogs = $query->matching($query->equals('name', $name))->execute(); return $blogs; } } Inspiring people to share
  • 39. The BlogRepository Now this really must be a complex piece of code, no? One word: No class BlogRepository extends F3::FLOW3::Persistence::Repository { /** * Returns one or more Blogs with a matching name if found. * * @param string $name The name to match against * @return array */ public function findByName($name) { $query = $this->createQuery(); $blogs = $query->matching($query->equals('name', $name))->execute(); return $blogs; } } Inspiring people to share
  • 40. @nnotations used @repository @entity @valueobject @var @transient @reference @identifier Inspiring people to share
  • 41. 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
  • 42. Simplified stack Application Application FLOW3 Persistence TYPO3 Content Repository PDO ... SQLite PgSQL MySQL ... Inspiring people to share
  • 43. Simplified stack FLOW3 Persistence TYPO3 Content Repository Inspiring people to share
  • 44. 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
  • 45. JSR-283 Repository Defines a uniform API for accessing content repositories A Content Repository • is a kind of object database for storage, search and retrieval of hierarchical data • provides methods for versioning, transactions and monitoring TYPO3CR is the first working port of JSR-170 / JSR-283 Karsten Dambekalns is member of the JSR-283 expert group Inspiring people to share
  • 46. Legacy databases Often you... • still need to access some existing RDBMS • need to put data somewhere for other systems to access The Content Repository will allow “mounting” of RDBMS tables Through this you can use the same persistence flow Inspiring people to share
  • 47. Legacy databases Often you... • still need to access some existing RDBMS future • fun! need to put data somewhere for other systems to access The Content Repository will allow “mounting” of RDBMS tables Through this you can use the same persistence flow Inspiring people to share
  • 48. 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
  • 49. 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
  • 50. Client code ignores Repository implementation; Developers do not! Eric Evans Inspiring people to share
  • 51. Usability Repositories extending FLOW3’s base Repository • have basic methods already • only need to implement custom find methods • already have a query object set up for “their” class No tables, no schema, no XML, no hassle No save calls, no fiddling with hierarchies Ready-to-use objects returned Inspiring people to share
  • 52. Questions! Inspiring people to share
  • 53. Literature Domain-Driven Design Eric Evans, Addison-Wesley Applying Domain-Driven Design and Patterns Jimmy Nilsson, Addison-Wesley Patterns of Enterprise Application Architecture Martin Fowler, Addison-Wesley Inspiring people to share
  • 54. Links FLOW3 http://flow3.typo3.org/ TYPO3CR http://forge.typo3.org/projects/show/package-typo3cr JSR-283 http://jcp.org/en/jsr/detail?id=283 Inspiring people to share
  • 55. Flickr photo credits: megapixel13 (barcode), rmrayner (ring), Ducatirider (grapes), Here’s Kate (book shelf) Pumpkin pictures: http://ptnoticias.com/pumpkinway/ Inspiring people to share

×