1

I am currently developing my first custom data mapper layer but have run into a conceptual problem that seems to be glossed over all books and guides I have read.

My problem is as follows. My data mapper knows the database and maps the database fields (from multiple tables, not shown in example) to the model fields. However, prior to me creating the DataMapper, my model fields where nicely encapsulated and only had getters.

Now, I had to create setters, despite the fact that I don't want them, the only class that should ever set values is the mapper (or the model itself). Is there any way around this?

I can think of two ways right now, but I don't really like either:

  1. Inject the mapper into the model via a static factory method, and let the model map the data mapper fields to its own fields. This would mean I more or less map things twice (from database to mapper fields, then from mapper fields to model fields) and it just feels very very wrong.

  2. Use __set instead of specific setters and use reflection to identify the calling class, only letting the correct mapper actually set values. My gripe with this is that I'd rather not use reflection in general and that I'd prefer a well-defined interface for the model.

Here are the relevant bits of code, in case they help understand my dilemma.

Controller:

$mapper = new Mapper();
$model = $mapper->find($id);
if ($model != null) {
    // hook up view with model
}

Mapper:

public function find($id)
{
    $pdoStatement = $this->database->select(static::getSelectStatement(), $id);
    if ($pdoStatement != null) {
        $values = $pdoStatement->fetch();
        if (!empty($values) {
            return $this->createObject($values);
        }
    }
}

private function createObject(array $values)
{
    $model = new Model($values['id']); // needs ID, legacy constraint
    // Now we come to the ugly part, setters I didn't need before
    $model->setTitle($values['title']);
    $model->setReleaseDate($values['date']);
    // etc.

return $model;
}
  • Are the setters you are calling for required attributes (must be set to a valid value) or optional attributes of Model? – Bart van Ingen Schenau Feb 22 '16 at 10:46
  • None of them would lead to non-working code if not set, but logically, yes, some of them are required – janb Feb 22 '16 at 10:54
  • Oops, posted to quickly. They might be required in the sense that e.g. in the example a model without title would be rather useless in terms of actually displaying it in a view – janb Feb 22 '16 at 10:55
  • my model fields where nicely encapsulated and only had getters -- some might say this is a contradiction. – Fuhrmanator Feb 22 '16 at 16:43
  • E.g. Doctrine uses reflection to directly set private properties of the model, so creating public setters is not needed. – amakhrov Mar 28 '16 at 3:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.