Подтвердить что ты не робот

Карта данных и отношения: стратегии реализации?

Я почти закончил свой Data Mapper, но теперь я нахожусь в точке, где дело касается отношений.

Я попытаюсь проиллюстрировать свои идеи здесь. Я не смог найти хорошие статьи/информацию по этой теме, поэтому, возможно, я заново изобретаю колесо (наверняка я, я мог бы просто использовать большую структуру, но я хочу учиться, делая это).

Отношения 1:1

Во-первых, давайте посмотрим на отношения 1:1. В общем, когда у нас есть класс домена под названием "Компания", а один называется "Адрес", наш класс компании будет иметь что-то вроде address_id. Допустим, в большинстве случаев мы просто показываем список компаний, и адрес нужен только тогда, когда кто-то смотрит на детали. В этом случае мой Data Mapper (CompanyDataMapper) просто загружается лениво, то есть он просто извлекает этот адрес_ид из базы данных, но не будет делать соединение, чтобы получить данные адреса.

В общем, у меня есть метод getter для каждого отношения. Таким образом, в этом случае есть метод getAddress (Company companyObject). Он принимает объект компании, ищет его свойство адреса и - если он NULL - выбирает соответствующий объект Address из базы данных, используя класс Mapper для этого объекта Address (AddressDataMapper) и присваивает этот адресный объект свойству адреса указанного объект компании.

Важно: разрешен ли Map Mapper использовать другой Data Mapper?

Допустим, что в большинстве случаев вам нужен как объект компании, так и адресный объект, потому что вы всегда показываете его в списке все вместе. В этом случае CompanyDataMapper не только извлекает объекты компании, но и SQL-запрос с JOIN также получает все поля адресного объекта. Наконец, он выполняет итерацию по набору записей и передает новые объекты с соответствующими значениями, присваивая объект адреса объекту компании.

Звучит просто, пока.

1: n Отношения

Как насчет этих? Единственное отличие от 1:1 состоит в том, что у Компании может быть несколько объектов Address. Давайте посмотрим: когда мы большую часть времени интересуемся только компанией, Data Mapper просто установит для свойства адресов объекта компании значение NULL. Свойство адресов - это массив, который может ссылаться на ни один, один или несколько адресов. Но мы еще не знаем, поскольку мы лениво загружаемся, так что это просто NULL. Но что, если нам понадобится все адреса в большинстве случаев? Если бы мы отобрали большой список со всеми компаниями вместе со всеми их адресами? В этом случае все начинает становиться действительно уродливым. Во-первых, мы не можем присоединиться к таблице адресов пятьдесят раз для каждого объекта адреса (я твердо верю, что это невозможно, и если это так, производительность будет ниже нуля). Итак, когда мы думаем об этом дальше по дороге, в этом случае невозможно ЛЮБИТЬ лениво.

Важно: Это правда? Должен ли я отправлять 100 запросов для получения 100 адресных объектов, если у меня 10 компаний с каждыми 10 адресами?

m: n Отношения

Предположим, что адресный объект содержит только страну, страну, город, дорогу и номер дома. Но один дом может быть большой бизнес-башней с множеством компаний в них. Как один из тех современных офисных зданий, где каждый может арендовать небольшой ром, чтобы показать эту башню на своем веб-сайте. Итак: многие компании могут использовать один и тот же адрес.

Я еще не планирую заниматься этой проблемой.

Важно: Вероятно, это не большая проблема, чем отношения 1: n?

Если кто-то знает хороший источник, который подробно рассказывает о его решении/реализации, я был бы рад ссылке!

4b9b3361

Ответ 1

Я с нетерпением жду любых ответов, которые вы получите по этой теме, но тем временем почему бы просто не перескочить на Amazon (или ваш локальный дилер книг) и, наконец, купить

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

Ответ 2

Прежде чем я начну, предположим, вы прочитали книгу PoEAA от Фаулера от начала до конца. знак равно Кроме того, я подумаю, что вы уже думали о первых начальных проблемах, с которыми вы сталкиваетесь при работе с ORM. Я могу выделить простой, например, несколько раз вызвать DataMapper с использованием того же идентификатора и всегда возвращать тот же объект (читайте как IdentityMap).

Важно: разрешен ли Map Mapper использовать другой Data Mapper?

Только один DataMapper может получить доступ к другому, если второй является слабым эталоном во втором.

Допустим, что в большинстве случаев вам нужен как объект компании, так и адресный объект, потому что вы всегда показываете его в списке все вместе. В этом случае CompanyDataMapper не только извлекает объекты компании, но и SQL-запрос с JOIN также получает все поля адресного объекта. Наконец, он выполняет итерацию по набору записей и передает новые объекты с соответствующими значениями, присваивая объект адреса объекту компании.

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

Прежде всего, у вас не должно быть getAddress (Company), но, скорее, полезно иметь объекты Proxy. Прокси - это неинициализированное представление данного экземпляра. В этом случае прокси содержит ссылку на запись, которую вы ищете. Он должен простираться от вашего исходного объекта и должен предоставить метод инициализации вместе с соответствующим DataMapper для его загрузки.

Вторая часть о подключении и загрузке нескольких объектов сразу называется Hydrator. Гидраторы получают плоскую структуру строк и столбцов и преобразуют в граф объектов. Но это действительно относится к отдельной проблеме: если вы чисто разбираетесь с объектами, почему вы извлекаете таблицы? Попытка взять подход к выбору объектов приведет к реализации своего рода OQL (Object Query Language).

Важно: Это правда? Должен ли я отправлять 100 запросов для получения 100 адресных объектов, если у меня 10 компаний с каждыми 10 адресами?

Работа с коллекцией объектов - это кошмар в PHP. Да, язык засасывает много из-за отсутствия мощной реализации коллекции. В принципе, вам необходимо иметь дело с различными ситуациями здесь: - новый экземпляр и все элементы в этом списке элементов являются новыми - новый экземпляр и все элементы в этом списке элементов уже существуют - новый экземпляр и элементы в этом списке элементов смешиваются между новыми и существующими - ранее существовавший экземпляр и ничего не трогающий в списке элементов - ранее существовавший экземпляр и манипулирование элементами в списке

Я очень упрощен здесь, но основным моментом, который я хочу подчеркнуть, является необходимость объекта Collection. Есть два из них: один, который касается новых списков и тот, который касается существующих списков. Тот, который имеет дело с существующими списками, должен иметь возможность загружать коллекцию, когда вы пытаетесь получить доступ к чему-либо внутри нее. Это единственный способ не иметь проблем с n + 1.

Здесь также подчеркивается следующая большая проблема, с которой вам придется столкнуться. Ассоциации могут быть однонаправленными или двунаправленными. Это означает, что компания знает, что адрес, но адрес не имеет понятия о том, что Компания является однонаправленной, а пользователь является частью многих групп и групп, в которых много пользователей, является двунаправленной ассоциацией. Вещи легко становятся кошмаром здесь и почему вам нужно, чтобы шаблоны сопоставления правильно понимали, что происходит.

Работа со многими-ко-многим - это то же самое, что и дело с коллекциями.

Есть важная часть, которую вы еще не рассмотрели. Если я построю весь графический объект ( "Компания и адрес" ), и я решил сохранить их... ему нужно удержать оба или мне нужно вручную сказать, что я хочу сохранить? Оба способа имеют разные проблемы. Предположим, вы хотите использовать первый подход. Вы только что вошли в то, что я считаю одним из самых сложных шаблонов проектирования для реализации: UnitOfWork. Тогда вам придется иметь дело с сортировкой порядка объектов, которые будут применяться, чтобы не создавать проблемы ограничения (прочитайте "Топологическая сортировка" о том, как это решить). Если вы возьмете второй подход, вы можете легко войти в ситуацию, когда он чувствует, что ваш инструмент сломан, главным образом потому, что очень легко иметь графический объект в несогласованном состоянии.

Наконец... планируете ли вы ЛЮБИТЬ поддержку наследования? Если положительно, ваше планирование просто вступило на совершенно новый уровень. = (Попробуем объяснить, возьмет ли я книгу. Но я могу указать некоторые шаблоны проектирования, на которые вы можете посмотреть: Наследование бетонных таблиц (1 класс, 1 таблица), Наследование отдельных таблиц (N классов, 1 таблица) и Наследование классов таблицы (N классы, таблицы M).

Я могу подробно рассказать о многих разных моментах здесь, но ORM обычно приводит к взрывам головы. Я остановлюсь сейчас.

PS: Я один из основных разработчиков Doctrine ORM. Если вы не делаете это для учебных целей, не беспокойтесь, пытаясь создать еще один. Это чрезвычайно сложное, трудоемкое время, и он требует много-много планирования, как все будет работать, прежде чем вы будете кодировать первую строку. По сути, мы планировали Doctrine ORM в течение 2 лет и заняли 1 год, чтобы надежно реализовать основные функции. Я не обескураживаю вас, но, как сказал Фаулер в своей статье о ненависти ORM, это сложное решение для даже сложной проблемы.

Ответ 3

Я тоже работаю над этой проблемой. Для начала я адаптировал шаблон Data Mapper из объектов PHP, шаблонов и практики Matt Zandstra (2d Ed). Теперь я вижу, что новая версия вышла

Возможно, самой изобретательной частью установки являются объекты "Коллекции". Я не уверен, какой язык вы используете, поэтому я пощажу вам подробности. Достаточно сказать, что PHP имеет интерфейс Iterator, который позволяет сначала загрузить массив (на карте, на других языках) и преобразовать необработанные данные в объекты (гидрат?) "На лету", а также цикл.

Как и вы, я борюсь с тем, как загружать отношения. То, что я нашел до сих пор, заключается в том, что я могу написать свой массивный запрос JOIN в классе Mapper и создать обе дегидратированную коллекцию для целевого объекта и прокрасться в данные о связанных объектах одновременно.

Мне очень не нравится "Lazy Load", потому что это приводит к так много запросов к базе данных. Это оскорбляет мою перфекционистскую чувствительность, чтобы знать, что я использую десятки или сотни запросов для выполнения, можно было бы сделать в одном.

Я тоже жду новых ответов.