Шаблон проектирования PHP для части модели [PHP Zend Framework] - PullRequest
0 голосов
/ 23 марта 2010

У меня есть приложение PHP MVC, использующее Zend Framework. Как показано в кратком обзоре, я использую 3 слоя для модели:

  • Модель (бизнес-логика)
  • Картограф данных
  • Шлюз данных таблиц (или объект доступа к данным, то есть один класс на таблицу SQL)

Модель разработана в UML и полностью независима от БД.

Моя проблема : у меня не может быть нескольких экземпляров одного и того же "экземпляра / записи".

Например, : если я получу, например, пользователя " Чак Норрис " с id = 5, это создаст новый экземпляр модели, члены которого будут заполнены преобразователь данных (преобразователь данных запрашивает шлюз данных таблицы, который запрашивает БД). Затем, если я изменю имя на «Duck Norras», не сохраню его сразу в БД и не перезагружу того же пользователя в другую переменную, у меня возникнут проблемы с «синхронизацией» ... ( разные экземпляры для та же " запись " )

Прямо сейчас я использую шаблон Multiton / Identity Map : как и Singleton, но несколько экземпляров индексируются по ключу (который в нашем примере - идентификатор пользователя) Но это сильно усложняет мою разработку и мои тесты тоже.

Как это правильно сделать?

Ответы [ 2 ]

1 голос
/ 23 марта 2010

Идентификационная карта

Редактировать

В ответ на этот комментарий:

Если у меня есть «select * from X», как я могу пропустить получение уже загруженных записей?

Вы не можете в самом запросе, но вы можете в логике, которая загружает строки в объекты сущностей. В псевдокоде:

class Person {}

class PersonMapper {
  protected $identity_map = array();
  function load($row) {
    if (!isset($this->identity_map[$row['id']])) {
      $person = new Person();
      foreach ($row as $key => $value) {
        $person->$key = $value;
      }
      $this->identity_map[$row['id']] = $person;
    }
    return $this->identity_map[$row['id']];
  }
}

class MappingIterator {
  function __construct($resultset, $mapper) {
    $this->resultset = $resultset;
    $this->mapper = $mapper;
  }
  function next() {
    $row = next($this->resultset);
    if ($row) {
      return $this->mapper->load($row);
    }
  }
}

На практике вы, вероятно, хотели бы, чтобы ваш MappingIterator реализовал Iterator, но я пропустил это для краткости.

0 голосов
/ 23 марта 2010

Храните все загруженные экземпляры модели в «живом пуле моделей».Когда вы загружаете / запрашиваете модель, сначала проверьте, была ли она уже загружена в пул (используйте первичный ключ или аналогичную концепцию).Если это так, вернуть объект (или ссылку) из пула.Таким образом, все ваши ссылки указывают на один и тот же объект.Моя терминология может быть неверной, но, надеюсь, вы поняли идею.В основном пул действует как кеш между бизнес-логикой и базой данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...