1

出于日志记录的目的,我想将各种类(为此我想要一种通用方法)调整为键值字典:这可以看作是“键值序列化”。

让我们假设键是预定义的,并且根据我们想要适应的输入类,每个值可能对应于一个特定的属性。值总是可以封装到 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++ 中是否有更通用的方法来实现这一点?你的设计会是什么?

谢谢!

更新

当一个新的客户端被实现时,日志引擎不应该改变:这就是为什么适配逻辑应该分布在客户端而不是在日志引擎的核心中实现。只有在需要新键时才会更新日志引擎(这可能意味着数据库结构发生变化)。

4

1 回答 1

0

我会为键和值存储序列化的字符串。
这里我使用的ldbSerialize是默认使用 boost 序列化的方法,并且可以很容易地专门化而无需创建新类。对于每一种新类型的键,只需添加一个新的专业化:

template <> inline void ldbSerialize<Key32> (string& bytes, const Key32& key) {
  bytes += key.whatever();
}
于 2012-12-28T10:48:53.760 回答