传入数据包版本处理 - 设计问题

时间:2013-12-15 00:11:50

标签: c++

考虑来自某个地方的数据包。它有字段VERSION,有N个可能的输入数据包版本。 对于从X到1的每个数据包VERSION,每个包含VERSION X的数据包都必须通过适当的方法/指令集进行处理。完成此任务的唯一想法非常难看:

PACKET p = GetPacketFromSomewhere();
// p.VERSION is 3

if (p.VERSION > 0) {
  // things for p.VERSION == 1
}

if (p.VERSION > 1) {
  // things for p.VERSION == 2
}

if (p.VERSION > 2) {
  // things for p.VERSION == 3
}

// set of if statements up to version N

真实的情况是,我的数据包VERSIONS高于10,事情仍有可能改变。当我需要保持向后兼容性时,将添加新的数据包VERSIONS。这段代码很糟糕,至少我不喜欢它。你们有更好的想法如何处理这种情况吗?

2 个答案:

答案 0 :(得分:2)

使用map类型map<unsigned int, function>,其中function是指向所需类型函数的指针:

typedef void (*function)();
std::map<int,function> handlers;
handlers[1] = &ver1handler;
...
handlers[N] = &verNhandler;

if(handlers.count(p.VERSION))
   (*handlers.find(p.VERSION))();

其中ver[N+1]handler定义为:

void ver[N+1]handler(){
   ver[N]handler();
   // additional handle commands
}

或者使用switch命令,并以相同的方式定义处理程序。

答案 1 :(得分:2)

如果处理顺序不重要,您可以使用不间断的开关:

PACKET p = GetPacketFromSomewhere();
// p.VERSION is 3

switch (p.VERSION) {
    case 3: {
        // things for p.VERSION == 3
    }
    case 2: {
        // things for p.VERSION == 2
    }
    case 1: {
        // things for p.VERSION == 1
    }
}

编辑: 您还可以使用递归函数模板特化:

template<int N>
void proc(PACKET& p){
    proc<N-1>(p);        
}

template<>
void proc<1>(PACKET& p){
     //things for p.VERSION == 1
}

template<>
void proc<2>(PACKET& p){
    proc<1>(p)
    //things for p.VERSION == 2
}

template<>
void proc<3>(PACKET& p){
    proc<2>(p)
    //things for p.VERSION == 3
}   

然后调用这样的处理函数:

switch (p.VERSION ) {
    case 1: proc<1>(p) break;
    case 3: proc<2>(p) break;
    case 3: proc<3>(p) break;
    default: {
        std::cout << "Protocol version not impplemented - using highest known version" << std::endl;
        proc<3>(p); 
}

这也应该是非常有效的性能(如果这是您的担忧),并且您不必担心协议版本中的差距。

相关问题