• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Architecting Your Models
 

Architecting Your Models

on

  • 26,720 views

Provides some approaches to the "M" in MVC -- Models -- and how to get away from tying models to your database, and instead adopt sane approaches that provide more flexibility and forward ...

Provides some approaches to the "M" in MVC -- Models -- and how to get away from tying models to your database, and instead adopt sane approaches that provide more flexibility and forward exapandibility in your code.

Statistics

Views

Total Views
26,720
Views on SlideShare
24,656
Embed Views
2,064

Actions

Likes
71
Downloads
722
Comments
7

19 Embeds 2,064

http://sasezaki.hatenablog.com 692
http://storify.com 631
http://www.kimbs.cn 256
http://www.laplacesdemon.com 216
http://www.slideshare.net 111
http://bleroutoolkit.wordpress.com 66
http://paper.li 20
http://twitter.com 19
http://www.techgig.com 17
https://twitter.com 8
http://kbs.kimbs.cn 6
http://a0.twimg.com 5
http://www.scoop.it 5
http://coderwall.com 4
http://translate.googleusercontent.com 3
http://test.idoc.vn 2
http://tricklet.net 1
http://translate.googleuser 1
https://www.linkedin.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

17 of 7 previous next Post a comment

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • nice :)
    Are you sure you want to
    Your message goes here
    Processing…
  • Hi,

    @gabreanuandrei, i'd like to add that what is so called 'domain logic' isn't limited to add behaviour inside your model classes representing the entities of the system. The business logic can live inside any class, and a service is not an exception. I think a 'well' (that's subjective) designed model layer can mix several approaches. If you take a look at Domain Driven Design for instance, you'll see that it introduces two different kind of services, one specific to the model, responsible of business operations, and being the glue between your models, and the second one dedicated to applicative code, but maybe that's the only aspect that you'll take from DDD, and you'll consolidate your approach being inspirated by other approaches radically different, and in the end, your model will be well organized, but also unique, unique for your project and unique for the business it is designed for, just like matthew pointed it out.

    I think that just opening a book and implementing your stuff exactly like it is 'right' is not necesseraly a good thing.

    At this time, i think that Matthew tried to have the best 'generic' approach he could have with the tools he had ;-)

    Today, it's not really a problem anymore since frameworks let your mind do the job !
    Are you sure you want to
    Your message goes here
    Processing…
  • @gabreanuandrei I want to point out a few things. First, this tutorial is almost 3 years old at this point. When I originally gave it, domain modelling in PHP was a fairly novel concept, and any information that moved developers away from having models directly extend objects that handled persistence (*ahem*ActiveRecord*ahem*) was a good step forward.

    Second: there are many, many valid ways to perform domain modelling. There is NOT a single correct way, however. Your choices will be informed by the project -- how big or small it is, how many developers you have, the complexity of the domain.

    Is the advice in the presentation _wrong_? I'd likely write a quite different presentation today -- but I wouldn't necessarily call the information in it inaccurate or bad. And yes, I've got a copy of Fowler's POEAA right next to me on my shelf, and have had my copy for many years. It's a guidebook, not a rulebook. ;-)
    Are you sure you want to
    Your message goes here
    Processing…
  • Isn't this tutorial actually bad? Based on Matin Fowler's article (and more on the web if you google) http://martinfowler.com/bliki/AnemicDomainModel.html - basically the Service should NOT contain logic at all rather than just guide the client into using the Domain Model properly but also provide a public API of your application to clients (controllers, API's, cli scripts, etc.)

    What do you think?
    Are you sure you want to
    Your message goes here
    Processing…
  • I'm curious as to how you'd separate the models from persistence when using an ORM like Doctrine.

    Doctrine seems to be engineered from the perspective that you'd be using the Doctrine_Record extending models directly.

    Cheers,
    Phil
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Architecting Your Models Architecting Your Models Presentation Transcript

    • Architecting Your Models Matthew Weier O'Phinney Project Lead Zend Framework
    • Goals
      • Learn to recognize why old habits may be bad
      • Learn several design patterns that can help you write testable, maintainable code
      • Learn some techniques for altering existing behavior without rewriting existing code
    • What We've Learned and What We Do
    • Oooh! Let's create the schema!
    • Write code that uses the DB
      • Plain Old Mysql (POM)
      • ActiveRecord
      • Table/Row Data Gateway
    • And then …
      • We start lamenting about performance.
      • We end up refactoring for every new feature (e.g. caching, logging).
      • We need to go to a Service Oriented Architecture, and effectively refactor twice.
    • STOP THE MADNESS!
    • Step One
    • Models are just classes. Create classes.
    • Models have metadata and behavior ; create properties and methods .
    • class Person implements PersonInterface { // Metadata protected $_email ; protected $_password ; protected $_username ; // Cheat: use overloading to // provide setters/getters public function __get( $name ) { } public function __set( $name , $value ) { } // Behaviors public function authenticate() { } public function logout() { } public function ban() { } }
    • Step Two
    • Now start thinking about data persistence .
      • 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 , ); class PersonTable extends Zend_Db_Table_Abstract { protected $_name = 'person' ; protected $_primary = 'username' ; }
    • Step Three
    • Map your model to your data.
    • Common approaches
      • Transaction Script (can even use POM)
      • Table Module (often with ActiveRecord or Table Data Gateway)
      • Data Mapper / ORM
    • class PersonMapper implements PersonMapperInterface { public function save(PersonInterface $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 ); }
    • Some notes:
      • Data !== Relational Database .
      • Data could come from a document database, filesystem, cache, or web service.
      • Choose an ORM that allows you to generate your schema from your entities; allows you to easily model first, and persistence comes for free.
    • Step Four
    • Move business and application logic to a Service Layer .
    • Applications are like onions; they have layers. Photo © 2008, Mike Chaput-Branson
    • The Service Layer provides application logic on top of your models
    • Service Layer in perspective Data Access Objects and Data store(s) Data Mappers Domain Models Service Layer
    • Benefits 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 model entities
    • 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
    • Decorators allow you to add or alter functionality of an existing class.
    • Typical decorators …
      • Implement the same interface(s) of the class being decorated
      • Often use overloading to proxy to the decorated class
      • Override specific behavior(s) you wish to modify or enhance
      • Add new behaviors that use existing behaviors in the decorated class
    • Refactor to add caching? No! Decorate!
    • class CachingPersonMapper implements PersonMapperInterface { public function __construct( PersonMapperInterface $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 to provide alternate return formats? (e.g., JSON, XML, etc.) No! Decorate!
    • class JsonPerson implements PersonInterface { public function __construct( PersonInterface $person ) { $this ->_person = $person ; } public function __toString() { $data = array ( 'username' => $this ->_person->username, 'email' => $this ->_person->email, ); return json_encode( $data ); } }
    • Nicely Formed Objects
      • Rebuilding and refactoring is costly and painful
      • Good OOP and encapsulation CAN make your life easier
      • Testing is easier than debugging
      • Choose a good ORM to expedite development. (Doctrine, Object Freezer, Zend_Entity, etc.)
    • Think beyond the DB!
    • Thank you!
      • Feedback: http://joind.in/918
      • Twitter: @weierophinney
      • Blog: http://weierophinney.net/matthew/