How should a data mapper return a domain object?

2k views Asked by At

In my model layer I have data mappers, domain objects, and "services" (to liase outside the model layer). I chose to implement a DomainObjectFactory and a DataMapperFactory, which has left me stuck on the DM<->DO relationship. Ideally the data mapper would return an instance (or an array of instances) of the related domain object for every method that performs a "get"/"read", but the data mapper doesn't have access to the domain object factory.

Without the factory pattern over the DM and DO, the autoloader could take over within the DM such that instances of the DO could be created. But how is this accomplished with a factory?

One possible solution I can think of would be to pass an instance of the related domain object to the data mapper method, e.g:

    $user = $this->domainObjectFactory->build('user');
    $mapper = $this->dataMapperFactory->build('userMapper');

    //Pass an [empty] user DO to the DM, which will be returned back
    $mapper->getById($someIDValue, $user);

This option seems very dirty, but it would work for single get methods. However it goes semantically off-the-rails when dealing with returning an array of domain objects, so clearly this isn't the best way to accomplish this... Another option would be to allow the data mapper access to the domain object factory, but that would turn into a massive LOD/SRP violation.

In short: How can a data mapper access the domain object factory to be able to return domain objects?

1

There are 1 answers

2
tereško On BEST ANSWER

I solve it like this:

$user = $this->domainObjectFactory->build('user');
$mapper = $this->dataMapperFactory->build('userMapper');

$user->setName('Foobar');
$mapper->fetch( $user );
// mapper acquires entries that are related to user with name `"Foobar"`
// and loads it into the domain object

The idea is that then retrieving data from storage, mapper uses the existing parameters of domain object as conditions. If you are dealing with a list of domain objects, you create a mapper with works with collections instead, and assign the condition(s) to that collection.

Also, you might find this answer indirectly related to your issue.