Библиотека классов с поддержкой нескольких постоянных стратегий - PullRequest
2 голосов
/ 22 сентября 2008

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

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

Ответы [ 4 ]

1 голос
/ 22 сентября 2008

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

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

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

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

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

1 голос
/ 22 сентября 2008

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

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

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

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

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

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

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

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

1 голос
/ 22 сентября 2008

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

0 голосов
/ 22 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...