Шаблон Data Mapper и дубликаты объектов - PullRequest
1 голос
/ 31 января 2009

Я использую шаблон отображения данных в разрабатываемом приложении PHP, и у меня есть вопрос. В настоящее время вы запрашиваете объект Site с определенным идентификатором, и преобразователь ищет строку, создает объект и возвращает его. Однако, если вы сделаете это снова для того же сайта, вы получите два разных объекта с одинаковыми данными. eg.:

$mapper = new Site_Mapper();
$a = $mapper->get(1);
$b = $mapper->get(1);

$a == $b // true
$a === $b // false

Итак, мой вопрос, должен ли я:

  1. Хранить экземпляры объектов Site в картограф, так что я могу проверить, если они уже существуют до создания новый (может быть проблемой, если есть несколько картографов одного и того же тип)
  2. Сделайте то же самое, что и # 1, но убедитесь, что есть только один экземпляр каждого картограф
  3. Сделайте то же самое, что и # 1, но используйте статическое свойство, так что несколько экземпляры не проблема
  4. Не беспокоиться об этом, потому что это вероятно не проблема

Ответы [ 3 ]

5 голосов
/ 04 января 2010

То, что вы ищете, это шаблон Identity Map . Будьте осторожны с так называемыми «несоответствиями при чтении». Пока вы используете «старый экземпляр», БД, возможно, уже была изменена. И пока вы редактируете свой объект, другой пользователь может получить его экземпляр, изменить его быстрее и быстрее сохранить. Затем другой объект отменяет все эти изменения снова. Хотя в Интернете, возможно, это не такая большая проблема, поскольку «страница» быстро просматривается, и ни один объект не выживает дольше нескольких долей секунды.

2 голосов
/ 20 сентября 2010

Я знаю, что вопрос задавался довольно давно, но все же хотел ответить на тот случай, если кто-то столкнется с подобной дилеммой. На самом деле все приведенные выше предложения № 1,2,3, сделанные автором, связаны друг с другом, и для их решения необходимо рассмотреть их все.

1) Сохраните каждый полученный из БД объект в маппере, чтобы вам не приходилось делать это снова, когда запрашивается объект с тем же идентификатором. Во всех последующих вызовах маппер должен возвращать сохраненный объект. Это называется IdentityMap pattern. Чтобы достичь этого, сделайте частное свойство в вашем преобразователе для хранения экземпляра IdentityMap для данного типа объекта. Метод Site_Mapper-> get () должен всегда проверять IdentityMap на предмет заданного идентификатора, если объект еще не получен, но маппер перейдет в базу данных, но если он уже сохранен в карте, он возвращает кэшированный экземпляр, который сохраняет поездку база данных. Таким образом, $ a === $ b должно быть истинным, поскольку они будут ссылками на один и тот же экземпляр объекта.

2) Да, в идеале всегда должен быть один экземпляр данного преобразователя данных (Site_Mapper), чтобы поддерживать один экземпляр IdentityMap в данный момент времени. Это можно сделать с помощью шаблона Singleton . Это возможно с некоторым методом получения, таким как Site_Mapper :: getInstance () , который всегда будет возвращать один и тот же экземпляр данного преобразователя. Вы также должны объявить __ construct () как частный метод, чтобы предотвратить нежелательное создание экземпляров с помощью new и убедиться, что getInstance () является единственным способом создать экземпляр картографа.

3) То, что автор упомянул выше о статических свойствах, также верно. Для реализации Singleton в PHP необходимо использовать статическое свойство для хранения и экземпляр Mapper.

Я бы настоятельно рекомендовал книгу Мартина Фаулера «Шаблоны архитектуры корпоративных приложений», в которой говорится о вышеупомянутых шаблонах и многом другом. Это хорошо читается, особенно если вы работаете над собственным решением ORM. Надеюсь, это поможет.

1 голос
/ 31 января 2009

Я бы как-то занялся кэшированием - классы статического сопоставления были бы моим первым выбором, и это то, что я видел больше всего. В противном случае ваш вариант 2 (который является одноэлементным шаблоном), вероятно, является лучшим вариантом.

Помните, что вам нужно очистить этот кеш при обновлении, чтобы избежать возврата устаревших данных.

Сказав, что, если вы не делаете что-то для широкого использования или не выполняете много запросов, это может не иметь значения. (твоя 4)

Также стоит обратить внимание на руководство (я уверен, что есть много примеров, я просто знаю этот лучше), Propel (http://propel.phpdb.org/) имеет функцию кэширования - возможно, стоит посмотреть, как это происходит? Или просто использовать это возможно?

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