Использование Zend_Db и нескольких таблиц - PullRequest
1 голос
/ 29 мая 2010

У меня есть нормализованная база данных, в которой хранятся местоположения файлов в Интернете. Файл может иметь несколько местоположений, распределенных по разным сайтам. Я храню URL-адреса в двух частях (Site.UrlStart, FileLocation.UrlEnd). UrlEnd - это часть, уникальная для этого файла (для сайта).

Упрощенная структура БД:

http://img231.imageshack.us/img231/9134/dblayout.jpg

Я использую Zend_Db в качестве моего ORM (если это так) с классами для таблиц, наследуемых от Zend_Db_Table_Abstract.

Проблема в том, что получение данных о местоположении (например, URL) требует использования нескольких таблиц и, насколько я могу разобрать, и мне придется либо использовать оба класса таблиц (тем самым раскрывая структуру моей таблицы), либо разбросать sql во всем моем приложении, ни один из которых не звучит привлекательно.

Единственное решение, которое я вижу, - это создать фасад, который действует как Zend_Db_Table_Abstract (может быть, наследует от него?) И скрывает тот факт, что данные фактически находятся в двух таблицах.

У меня следующие вопросы:

  • Собираюсь ли я в правильном направлении при создании класса фасада (есть ли другие альтернативы)?
  • Должен ли класс фасада наследоваться от Zend_Db_Table_Abstract?

1 Ответ

10 голосов
/ 29 мая 2010

Zend Db Table на самом деле не ORM за очень простыми вариантами использования. Он должен быть тесно связан с каждой таблицей в вашей системе. Таким образом, у вас будет один класс Zend_Db_Table для каждой таблицы.

Чтобы управлять более широкой картиной, вам понадобится другой тип класса.

Итак, да, вы находитесь на правильном пути в отношении использования своего рода фасада.

Однако я бы не стал наследовать его от Zend_Db_Table_Abstract, поскольку у него совершенно другой набор обязанностей.

Возможно, стоит взглянуть на шаблон Data Mapper, который похож на фасад (Мартин Фаулер, Patterns Of Enterprise Architecture). У вас будет один Mapper для «Типа доменного объекта» (который не обязательно совпадает с одним для таблицы) и, возможно, другой, дополнительный, Mapper для целого семейства типов.

Простой пример шаблонов Data Mapper приведен на вступительных страницах Zend Framework: http://framework.zend.com/manual/en/learning.quickstart.create-model.html

Обратите внимание, как Application_Model_GuestbookMapper использует Application_Model_DbTable_Guestbook - и не расширяет его.

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

Еще одним хорошим источником информации о том, как сопоставить БД с вашей моделью, является Скотт Амблер

статья онлайн: http://www.agiledata.org/essays/mappingObjects.html

Это охватывает процесс работы с отношениями между данными к данным, объектом к объекту и данными к объекту: http://www.agiledata.org/essays/mappingObjects.html#MappingRelationships

Он также касается шаблона сопоставления данных и является одним из немногих мест, где вы можете найти хорошее объяснение того, как сопоставить иерархии классов с таблицами БД.

Также Эрик Эванс описал использование «Хранилищ», которые являются фасадами, которые находятся между вашей моделью и уровнем данных. Это может быть быстрой отправной точкой, если создание полноценного ORM с Data Mappers кажется утомительным. Как правило, у вас есть один репозиторий для каждого важного доменного объекта (т. Е. Агрегированных корневых объектов, «стеблей гроздей винограда»).

Подробнее о репозиториях: http://books.google.co.uk/books?id=7dlaMs0SECsC&lpg=PP1&dq=Domain-Driven%20Design&pg=PA147#v=onepage&q&f=false

По сути, репозиторий имеет, среди прочего, методы типа FindById (), которые затем могут инкапсулировать использование ваших трех объектов Zend Db Table за своим фасадом. Ваша модель может сразу начать использовать «Репо». Затем, однажды, если вы хотите добавить больше модных вещей ORM, вы просто меняете их за фасадом репо, и ваша модель даже не должна об этом знать.

Если эти три таблицы представляют собой сущности, ведущие независимую жизнь, то может быть лучше иметь три набора классов, которые управляют каждым из их жизненных циклов. Если это так, то вы должны использовать «Службу» (в частности, другую из Паттернов Эрика Эванса) для управления их взаимодействиями. Служба - это место для размещения операций, которые, похоже, не подходят никому, исключительной сущности.

см .: http://books.google.co.uk/books?id=7dlaMs0SECsC&lpg=PP1&dq=Domain-Driven%20Design&pg=PA106#v=onepage&q=service&f=false

Суть в том, чтобы психологически отделить себя от доминирования Zend Db Table - это всего лишь второстепенный игрок, представление таблиц db и не намного.

...