Абстрагирование конкретных идентификаторов базы данных с шаблоном хранилища? - PullRequest
4 голосов
/ 11 августа 2011

Я изучаю DDD (дизайн, управляемый доменом) и шаблон репозитория (в C #). Я хотел бы иметь возможность использовать шаблон репозитория для сохранения сущности и не заботиться о том, какая база данных фактически используется (Oracle, MySQL, MongoDB, RavenDB и т. Д.). Я, однако, не уверен, как обрабатывать специфичные для базы данных идентификаторы: большинство (все?) Баз данных использует. Например, RavenDB требует, чтобы каждый объект, который он должен хранить, имел свойство id типа string. Другим может потребоваться свойство id типа int. Поскольку разные базы данных обрабатывают это по-разному, я не могу сделать идентификатор базы данных частью класса сущностей. Но это должно было бы существовать в какой-то момент, по крайней мере, когда я храню фактическую сущность. Мой вопрос, какова лучшая практика в этом отношении?

Идея, которую я сейчас преследую, заключается в том, чтобы для каждой базы данных, которую я хочу поддерживать, реализовать специфические для базы данных «объекты значений» для каждого типа бизнес-объектов. Эти значения объекта будут иметь свойство базы данных, и я буду отображать между ними при чтении и записи. Это хорошая идея?

Ответы [ 4 ]

3 голосов
/ 12 августа 2011

Это классический случай утечки абстракций. Вы не можете абстрагироваться от типа базы данных в интерфейсе репозитория, если не хотите потерять все хорошее, что есть в каждой базе данных. Требования к типу удостоверения личности (строка, Guid или что-то еще) являются лишь самой вершиной огромного айсберга, большая часть его массы находится под грязными водами.

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

Относительно легко заставить вашу модель домена хорошо работать с любой СУБД. Большинство из них имеют стандартизированные типы данных. Использование ORM, например, NHibernate, вам очень поможет. Гораздо сложнее добиться того же в базах данных NoSQL, потому что они сильно отличаются (что на самом деле очень хорошо).

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

Если это не сработает, подумайте о Event Sourcing. Хранилище событий - один из наименее требовательных методов сохранения. Использование библиотеки, такой как EventStore Джонатана Оливера, позволит вам использовать практически любую технологию хранения, включая файловую систему.

1 голос
/ 16 июля 2014
  1. Вы делаете правильную вещь!Абстрагируйтесь от ограничений типов первичных ключей баз данных!

  2. Не пытайтесь переводить типы, просто используйте другое поле.

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

Затем ваши ограничения, на которых базы данных могут сохраняться, ваши объекты изменились с «должен иметь первичный ключ типа xxxx» на «простой», должен быть в состоянии хранить тип xxxx ».Я думаю, вы потом найдете, что не сможете использовать любую базу данных в мире.Удачного кодирования!DDD - лучший!

1 голос
/ 29 ноября 2011

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

0 голосов
/ 11 августа 2011

Вы можете потенциально иметь идентификаторы в объекте, но не выставлять его как часть открытого интерфейса объекта.Это возможно с NHibernate, потому что позволяет сопоставить столбец таблицы с частным полем.

Таким образом, у вас может быть что-то вроде

class Customer {
        private readonly Int32? _relationalId;
        private readonly String? _documentId;
        ...

Это не идеально, потому что ваша логика постоянства «расходится» с бизнес-логикой, но, учитывая требования, она, вероятно, проще и надежнее, чем поддержка отображениямежду сущностью и ее идентификатором где-то вне сущности.Я также настоятельно рекомендую вам оценить подход «независимость от базы данных», который был бы более реалистичным, если вы хотите поддерживать только реляционные базы данных.В этом случае вы можете по крайней мере повторно использовать ORM, как NHibernate, для реализации своего репозитория.И большинство реляционных баз данных поддерживают идентичные типы идентификаторов.В вашем сценарии вам нужен не только ORM, но и что-то вроде «Object-Document-Mapper».Я вижу, что вам придется писать тонны и тонны кода инфраструктуры.Я настоятельно рекомендую вам пересмотреть ваши требования и выбрать между реляционной базой данных и базой документов .Прочитайте это: Плюсы / минусы баз данных на основе документов и реляционных баз данных

...