Play-Doh: Modelling Your Objects
Upcoming SlideShare
Loading in...5
×
 

Play-Doh: Modelling Your Objects

on

  • 11,307 views

Short un-conference tutorial showing how to create your models in a way that is data layer independent, testable, and extensible.

Short un-conference tutorial showing how to create your models in a way that is data layer independent, testable, and extensible.

Statistics

Views

Total Views
11,307
Views on SlideShare
11,275
Embed Views
32

Actions

Likes
9
Downloads
105
Comments
3

4 Embeds 32

http://www.slideshare.net 24
http://www.php-talks.com 4
http://www.linkedin.com 3
http://translate.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Thanks for your quick answer.
    I got your point about the save() method.
    I think i was wrong while thinking about this, and as you say, the object which saves, also does the instrospection to know what to do, but i thought differently while asking the question.
    I read some of your article on your blog covering a similar approach and it was quite interesting.
    The introducing of a Mapper & a Service which could be decorated is a quite interesting point.
    I would be happy if you have some documents/links about relational mapping.
    Thanks again for your works
    Are you sure you want to
    Your message goes here
    Processing…
  • Relational mapping is very difficult, and was way beyond the scope of this presentation. The primary purpose of the presentation was to get PHP developers to start thinking beyond the RDBMS and instead focus on the objects they're manipulating. I mention ORMs briefly within this presentation as they can be used to solve some of the problems of persisting your models (though since ORMs are typically RDBMS-specific, they do not answer the question of persisting through document databases or web services) -- but there was no time to go into detail on that subject.

    As for save() vs. insert()/update(), save() is used in many ORMs, ActiveRecord, and Table Data Gateway implementations because it simplifies the interface. You do not need to know how the object was instantiated -- i.e., was it loaded from the persistence store, or is it a newly created object -- you simply save() it. save() then does the introspection of the object for you and decides if it is an update() or insert() operation -- and when done, updates the object from the persistence store.
    Are you sure you want to
    Your message goes here
    Processing…
  • Insteresting slide, but it covers only simple cases.
    What would have been insteresting is to cover classic problems like relational tables mapping.
    For example, how do you handle a Post domain object and a User domain object.
    Do you write a new PostUser object ? do you include userId, or userObject within the Post object ?

    Another point is, if i save i need to know if i update, or i insert, which is often simple to know for me because, if the userId is present in the object, i know the object has been retrieved from the DB, and then need to be updated, not inserted.
    Then, it is insteresting to return the new User object with its userId, but it could break the pattern.
    What do you think about this ?
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Play-Doh: Modelling Your Objects Play-Doh: Modelling Your Objects Presentation Transcript

  • Play-Doh: Modelling your Objects Matthew Weier O'Phinney Project Lead Zend Framework
  • What we've learned and what we do
  • Oooh! Let's create the schema!
  • Write code that uses the DB
    • Object Relational Mapping (ORM)
    • ActiveRecord
    • Table/Row Data Gateway
    • Plain Old Mysql (POM)
  • And then …
    • we start lamenting about performance
    • we end up refactoring for every new feature (esp. caching, logging)
    • we need to go to a Service Oriented Architecture, and refactor twice
  • STOP THE MADNESS!
  • Step One
  • Models are just classes. Create classes.
  • < ?php class Person { protected $_email ; protected $_password ; protected $_username ; public function __get ( $name ) { $local = '_' . $name ; if ( property_exists ( $this , $local )) { return $this -> $local ; } return null ; } public function __set ( $name , $value ) { $local = '_' . $name ; if (! property_exists ( $this , $local )) { throw new InvalidArgumentException (); } $this -> $local = $value ; } }
  • Step Two
    • Identify what data you need to persist
    • Identify how you'll persist the data
    • Write code for persisting data (Data Access Layer)
  • CREATE TABLE person ( username VARCHAR PRIMARY KEY , password VARCHAR , email VARCHAR , ); < ?php class PersonTable extends Zend_Db_Table_Abstract { protected $_name = 'person' ; protected $_primary = 'username' ; }
  • Step Three
    • Map your model to your data:
      • Data Mapper
      • Transaction Script
  • < ?php class PersonMapper { public function save ( Person $person ) { $data = array ( 'username' => $person -> username , 'password' => $person -> password , 'email' => $person -> email , ); $this -> getTable ()-> save ( $data ); } public function fetch ( $username ); public function getTable (); public function setTable ( $table ); }
  • Step Four
    • Move application logic to a Service Layer
      • Allows easy consumption of the application via your MVC layer
      • Allows easy re-use of your application via services
      • Write CLI scripts that consume the Service Layer
    • What kind of application logic?
      • Validation and filtering
      • Authentication and Authorization
      • Transactions and interactions between models
  • < ?php class PersonService { public function create ( array $data ) { $person = new Person (); if (! $data = $this -> getValidator ()-> isValid ( $data )) { throw new InvalidArgumentException (); } $person -> username = $data [ 'username' ]; $person -> password = $data [ 'password' ]; $person -> email = $data [ 'email' ]; $this -> getMapper ()-> save ( $person ); return $person ; } }
  • Decorating for Fun and Profit
  • Refactor to add caching? No! Decorate!
  • < ?php class CachingPersonMapper { protected $_mapper ; public function __construct ( PersonMapper $mapper ) { $this -> _mapper = $mapper ; } public function fetch ( $username ) { $cache = $this -> getCache (); if (! $person = $cache -> load ( $username )) { $person = $this -> _mapper -> fetch ( $username ); $cache -> save ( $person , $username ); } return $person ; } }
  • Refactor or extend to change the return value (e.g., JSON vs XML vs ...)? No! Decorate!
  • < ?php class JsonPerson { protected $_person ; public function __construct ( Person $person ) { $this -> _person = $person ; } public function __toString () { $data = array ( 'username' => $this -> _person -> username , 'email' => $this -> _person -> email , ); return json_encode ( $data ); } }
  • Congratulations!
    • Rebuilding and refactoring is costly and painful
    • Good OOP and encapsulation CAN make your life easier
    • Testing is easier than debugging
  • Think beyond the DB!
  • Thank you.