C ++ поддерживает множественное наследование, поэтому вы можете иметь общий API персистентности и наследовать механизм персистентности. Для этого все равно придется использовать самоанализ для получения метаданных класса, но у вас все равно будет эта проблема с любым постоянным слоем.
В качестве альтернативы вы можете сделать что-то подобное, но использовать метаданные для управления генератором кода, который заполняет 'Getters' и 'Setters' для уровня постоянства.
Любой постоянный уровень обычно использует тот или иной подход, поэтому ваша проблема заключается в подключении механизма загрузки к постоянному слою. Я думаю, что это немного отличает вашу проблему от одного уровня персистентности, но решает ее с другой стороны. Вместо того, чтобы строить классы домена на каркасе постоянства, вы предоставляете набор классов домена с крючками для каркаса постоянства, в которые третьи стороны могут подключить свой механизм доступа к данным.
Я думаю, что когда вы предоставляете доступ к метаданным класса и обратным вызовам, механизм постоянства становится относительно простым. Посмотрите на компоненты метаданных любой удобной среды отображения C / O и R и поймите, как они работают. Инкапсулируйте это с помощью API в одном из базовых классов классов вашего домена и предоставьте универсальный API-метод получения / установки для создания или сохранения. Остальное зависит от того, кто реализует постоянный слой.
Редактировать: Я не могу представить библиотеку C ++ с типом подключаемого механизма сохранения, который вы описываете, но я сделал кое-что в Python, в котором могли бы быть добавлены средства такого типа. Конкретная реализация использовала средства в Python без прямого эквивалента C ++, хотя основной принцип, вероятно, можно было бы адаптировать для работы с C ++.
В Python вы можете перехватывать доступ к переменным экземпляра, переопределяя __getattr()__
и __setattr()__
. Механизм постоянства фактически поддерживал свой собственный кэш данных за кулисами. Когда функциональные возможности были смешаны с классом (выполненным посредством множественного наследования), он отменял поведение системы по умолчанию для доступа к элементу и проверял, соответствует ли запрашиваемый атрибут чему-либо в его словаре. Там, где это произошло, вызов был перенаправлен для получения или установки элемента в кеше данных.
Кэш имел собственные метаданные. Он знал об отношениях между сущностями в своей модели данных и знал, какие имена атрибутов необходимо перехватить для доступа к данным. То, как это работало, отделяло его от уровня доступа к базе данных и могло (по крайней мере, теоретически) позволить использовать механизм персистентности с разными драйверами. Не существует внутренней причины, по которой вы не могли бы (например) создать драйвер, сериализовавший его в файл XML.
Сделать что-то подобное в C ++ было бы немного сложнее, и, возможно, было бы невозможно сделать доступ к объектному кешу таким же прозрачным, как это было в этой системе. Возможно, вам лучше использовать явный протокол, который загружает и сбрасывает состояние объекта в кэш. Код для этого вполне поддается генерации из метаданных кэша, но это должно быть сделано во время компиляции. Вы можете сделать что-то с шаблонами или переопределить оператор ->
, чтобы сделать протокол доступа более прозрачным, но это, вероятно, больше проблем, чем оно того стоит.