I’ve always worked with various ORM’s in the past and placed all my logic inside my models regardless of it’s nature – SQL, MongoDB queries & even fetching of remote JSON objects.
But when it’s necessary to ensure loose couplings to allow a high level of testability, the issues of this methodology quickly appears.
Today I’ve read about separating models into two parts, Domain objects & Data mappers.
If I understood it completely, Domain objects are completely unaware of the storage used, and instead exists to handle business logic. Data mappers on the other hand takes care of storing the data set in the Domain objects to a set data storage.
I do however find it a bit hard to find a good, easy-to-understand example online on how to work with the DomainObjects & DataMappers in a real world example.
Would this (below shown code) be the appropriate way to work with DomainObjects & DataMappers in my code to store Users or have I gotten it all wrong in my head?
$user = new User_DO;
$userSave = new User_DM;
$userSave->store( $user->add(array('name' => 'John Doe')) );
class User_DO {
function add($array) {
if(!isset($array['name'])) {
throw new Exception("Name must be set");
}
return $array;
}
}
class User_DM {
function store($array) {
MyDatabase::execute("INSERT INTO...");
}
}
The idea behind this is to have a standard object, that represents the current state in real life or in other words, in the domain. This domain model is usually a collection of data without logic.
The loading of instances of this domain model (domain objects) and the persistence is handled through data mappers – e.g. the address of the above person might be located in another table via a 1:n relationship, as such:
The person_DO does not need to know about that, but the datamapper does, as it has to aggregate the data during loading and separate during persisting:
In order to decouple the different parts even more, the DataMappers usually use the DbTable Gateway or a similar pattern to allow the use of different databases or similar actions. That way, I can have several databases with the same schemas, but e.g. in different organizations to build a data warehouse with the same code, only different database objects.
As a practical example, I would suggest looking at the Quickstart Tutorial of the Zend Framework, which does exactly what I just explained briefly.