This again is a kind of persistence pattern. But it differs from Active Record pattern. Generally when there is a very simple domain logic one tends to go with Active Record pattern. But as the system starts getting complex with the need to cater to either legacy database system or complex domain logic , i would prefer switching to Data mapper pattern.
Data Mapper also decouples your domain model classes from the persistence store. That might be important for cases where you need to reuse the domain model with different database engines, schemas, or even different storage mechanisms altogether. Thus it gives more flexibility to design the database and the domain model differently i.e irrespective of each others progress. This is now being widely used in applications where you want to implement Automated test. This becomes of utmost need when you have a complex domain logic which needs to be auto tested but you want it to be disconnected from the database (due to corruption or heavy load) . Thus DataMapper pattern gives you this flexibility.
So now giving a comparison between the Active Pattern (diagram shown below) and the DataMapper.
You can see that all the Functionality is taken care by a single Active class. We will remove this overload for the class considering the complex domain logic and create a new class called AddressDataMapper which will take care of this functionality as shown below .
We might want to keep the Address Mapper still part of the Domain Logic/ layer , as Mappers need access to the fields in the domain objects. In Addition you can have a single handler with lots of CRUD operation for different Domain model or for each you can create your own Mapper. I would prefer the later as this again gives you more flexibility .
Ideally your Presentation code would perform some operation or request for information for which your Domain logic would serve the required back. This works independently from the database . Ideally you would load some information for each domain object right in the beginning . So your DataMapper will first try to search in a local session (Session Design Pattern) and if it is not found it would pass a database call asking for information. If the requested information is found in the session an unnecessary call to the database would avoided.
A simple example for the above, from Martin Fowler is as below :
There are again few more design patterns which goes with DataMapper viz. Repository , Unit of Work , Session , Lazy Loading for making the above job easier and further improve performance . We will be looking at these in the coming blogs .