В целях ведения журнала я хотел бы адаптировать различные классы (по этой причине я хотел бы использовать общий подход) к словарю значений ключа: это можно рассматривать как «сериализацию значения ключа».
Давайте предположим, что ключи предопределены и что в зависимости от входного класса, который мы хотим адаптировать, каждое значение может соответствовать определенному атрибуту.
Значения всегда могут быть заключены в std :: string.
Это был бы мой подход:
Создайте класс адаптера, который можно поместить в базу данных.
#include <keys.h> // enum with possible keys, defining type Key_t
namespace generic
{
class Adapter
{
public:
Adapter();
virtual ~Adapter();
virtual void init() = 0;
private:
std::map<Key_t, std::string> _data;
}
}
Для каждого возможного клиента специализируйте класс адаптера в его пространстве имен, предполагая, что он дружит с конкретной моделью бизнес-объекта любого клиента (для легкого доступа к атрибутам), и что он получает экземпляры таких моделей через ссылки const в своем конструкторе.
например
#include <generic/Adapter.h>
#include <client1/bom1.h>
#include <client1/bom2.h>
...
#include <client1/bomN.h>
namespace client1
{
class Adapter : public generic::Adapter
{
public:
Adapter(const Bom1& bom1,
const Bom2& bom2,
const BomN& bomN)
: _bom1(bom1), _bom2(bom2), _bomN(bomN)
{}
void init()
{
// Explicit data mapping in here
_map[NAME] = _bom1._name;
_map[TITLE] = _bom2._title;
....
....
}
private:
Bom1 _bom1;
Bom2 _bom2;
BomN _bomN;
}
}
Что вы думаете об этом подходе?
Есть ли более общий способ достижения этого в c ++?
Каким был бы ваш дизайн?
Спасибо!
Обновить
Когда внедряется новый клиент, механизм ведения журнала не должен меняться: именно поэтому логика адаптации должна распространяться на стороне клиента, а не внедряться в ядро механизма ведения журнала.
Механизм ведения журнала будет обновляться только в том случае, если требуются новые ключи (это, вероятно, будет означать структурное изменение базы данных).
Я бы сохранил сериализованные строки для ключей и значений.
Вот Я использую ldbSerialize
метод, который использует повышение сериализации по умолчанию и может быть легко специализирован без создания нового класса. Для каждого нового типа ключа можно просто добавить новую специализацию:
template <> inline void ldbSerialize<Key32> (string& bytes, const Key32& key) {
bytes += key.whatever();
}
Других решений пока нет …