Библиотека классов с поддержкой нескольких стратегий сохранения.

StackOverflow https://stackoverflow.com/questions/113818

Вопрос

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

Другие советы

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top