From the Doctrine 2.x branch, that requires Php 5.3 (that is now on RC), the pattern UnitOfWork is correctly implemented and also model classes don't extend a base one (it was Doctrine_Record). Persistence ignorance is the concept of having the domain classes (the User, PhoneNumber, Group, and so on, ones) not depending on framework or database abstraction layer components.
DDD to the resque
This concept is the core of Domain-Driven Design, an approach to build very complex enterprise applications: the persistence ignorance allows you to test very complex logic on the domain object (like an User with ten methods that computes data basing on his internal fields) without touching the database. It is the persistence layer that is dependent on the domain objects, and has to find a way to saving them anywhere (DataMapper and Repository patterns). Orms persist these objects in a relational database and can be a component of a Repository. Doctrine 2.0 could be a DataMapper.
DDD is hard: difficult to learn and to implement in an application, but basic concepts can help a developer allowing him to build a low coupled object graph and I think Doctrine should support some DDD patterns. This can attract php developers to Doctrine, and not only who uses an Orm to lessen his work, but also who wants to develop clean applications and Test-Driven Development, or who has internalized SOLID principles and is in the mood of writing cohesive and decoupled code.
Php lacks a DataMapper implementation that has the following of Doctrine and the features it offers.
My proposal
What I'd like to include in Doctrine are something which in the 1.x branch would be Doctrine_Template subclasses, also known as behaviors (the actAs option of yaml modelling). This template could be named Entity, ValueObject and Aggregate, in a DDD fashion. They would influence the behavior of data persistence and retrievel, for example let's say that Group actAs an Entity and PhoneNumber actAs a ValueObject; given that user has some relations to them, its array representation could be:
User [
name => Giorgio,
PhoneNumbers => [
[0] => [ value => 5551234],
[1] => [ value => 5557890],
],
Group => 23 // group id
]
Thinking of php environment (web pages but also cli), marking with high-level concepts the models with these behaviors (and also options if needed) will given the introspection to:
- generate forms for editing on the fly where ValueObjects are edited in place (for instance with input elements with name like Phonenumbers[0][value]), while Entities are represented with single and multiple selects, since the former have no identity and can be interchanged, while the latter have many data that cannot be included every time and a strong identity (as a user you insert your phonenumber but choose the group to belong to). This would not be the job of Doctrine but it can be accomplished with Zend_Form and other framework that works on the html side.
- these forms would validate a POST request basing on the doctrine model, thus keeping the validation rules in one place (the domain) and not building javascript and php validation rules which mirror the domain ones.
- Aggregate elements could have default hydration rules to include all children elements. More precisely, elements which are roots of aggregates: that means they are like the User of this example. You certainly want a Repository for User instances but not for searching single PhoneNumbers, that have only a value field.
- Aggregates can also simplify relations jungle, since it is not necessary for PhoneNumber to know which user owns them. The User aggregate is taking care on which user PhoneNumbers are.
I can work on 2.x branch and I'm proposing these additions to make a bit of DDD possible in Php without losing the capabilities of a general Orm layer (and have to write a custom one). Evaluate this chance.
Subscribe to feed to remain always updated on new articles
Something is wrong? Let us know...
Last comments
Redrigo in article Disqus and Zend Frameworkwhirlwind in article Code introspection and how to fool PHPUnit
Don in article Doctrine proposal: Entity and ValueObject
Giorgio Sironi in article Doctrine proposal: Entity and ValueObject
Don in article Doctrine proposal: Entity and ValueObject
Giorgio Sironi in article Are dynamic languages evil?
Ricky Clarkson in article Are dynamic languages evil?
Giancarlo Frison in article Are dynamic languages evil?
Giorgio Sironi in article In-memory, but persistent, testing with Sqlite
kgadkvve in article In-memory, but persistent, testing with Sqlite