2008-09-22 20 views
2

Я разрабатываю библиотеку классов C++, содержащую классы модели домена, и я хотел бы добавить поддержку для создания экземпляров этих классов из различных механизмов сохранения, то есть баз данных и файла. Пользователю библиотеки классов должен быть предоставлен интерфейс (?), С помощью которого можно запрограммировать класс, который может передавать данные из/в механизм сохранения.Библиотека классов с поддержкой нескольких стратегий персистентности

Я знаю шаблон объекта доступа к данным, который, похоже, работает на Java, но я не совсем уверен, как применить его к C++. Существуют ли другие решения?

ответ

1

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

Альтернативно вы можете сделать что-то подобное, но использовать метаданные для генерации генератора кода, который заполняет «Getters» и «Setters» для слоя persistence.

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

Я думаю, что как только вы предоставите доступ к метаданным класса и обратным вызовам, механизм perisistence будет относительно прост. Посмотрите на компоненты метаданных любой удобной C++ структуры отображения O/R и поймите, как они работают. Инкапсулируйте это с помощью API в один из базовых классов ваших классов домена и предоставьте общий API-интерфейс getter/setter для создания или сохранения. Остальное зависит от человека, реализующего слой сохранения.

Редактировать: Я не могу придумать библиотеку C++ с типом используемого механизма переноса, который вы описываете, но я сделал что-то в Python, который мог бы добавить этот тип объекта. Конкретная реализация использовала объекты в Python без прямого эквивалента C++, хотя основной принцип, вероятно, можно было бы адаптировать для работы с C++.

В Python вы можете перехватывать обращения к переменным экземпляра, переопределяя __getattr()__ и __setattr()__. Механизм сохранения фактически сохранил свой собственный кеш данных за кулисами. Когда функциональность была смешана с классом (выполнялась через множественное наследование), он переопределял поведение системы по умолчанию для доступа к члену и проверял, соответствует ли запрашиваемый атрибут чем-либо в его словаре. В этом случае вызов был перенаправлен для получения или установки элемента в кеше данных.

Кэш имел собственные метаданные. Он знал о взаимоотношениях между объектами в своей модели данных и знал, какие имена атрибутов перехватывают для доступа к данным. То, как это сработало, отделило его от уровня доступа к базе данных и могло (по крайней мере теоретически) позволить использовать механизм сохранения с разными драйверами.Не существует неотъемлемой причины, по которой вы не могли (например) построить драйвер, который сериализовал его в XML-файл.

Сделать что-то вроде этой работы на C++ было бы немного сложнее, и может оказаться невозможным сделать доступ к кешу объектов прозрачным, как это было с этой системой. Вероятно, вам будет лучше с явным протоколом, который загружает и удаляет состояние объекта в кеш. Код для этого был бы вполне поддающимся генерации из метаданных кеша, но это нужно было бы сделать во время компиляции. Возможно, вы сможете что-то сделать с помощью шаблонов или переопределить оператор ->, чтобы сделать протокол доступа более прозрачным, но это, вероятно, больше проблем, чем того стоит.

+0

Спасибо за обширный ответ. Не могли бы вы добавить примерный код или ссылку на некоторые примеры из общедоступного домена? – 2010-02-10 13:50:18

1

Boost Serialization содержит некоторые полезные материалы для работы с сериализацией типов C++, но насколько хорошо он будет соответствовать интерфейсу, который вы хотите, которого я не знаю. Он поддерживает как интрузивные, так и неинтрузивные конструкции, поэтому довольно гибкий.

0

Возможно, вам понравится boost serialization. Не воспользовавшись им, я не могу сказать, рекомендовать его или нет. Библиотеки Boost обычно имеют высокое качество.

1

Я бы избегал сериализации, IMHO, мы реализовали это для одного из наших приложений в MFC еще в 1995 году, мы были достаточно умны, чтобы использовать независимое управление версиями объектов и файловое управление версиями, но в итоге вы получаете много старого беспорядочного кода вокруг после времени.

Представьте себе определенные сценарии, устаревшие классы, устаревшие члены и т. Д., Каждый из них представляет новую проблему. Теперь мы используем сжатые потоки «типа XML», мы можем добавлять новые данные и поддерживать обратную совместимость.

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

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

Кроме того, использование стандартного формата данных с использованием некоторого запатентованного ключа означает, что его гораздо проще работать с третьими сторонами.