好的,上下文是一些序列化/反序列化代码,它将字节流解析为更易于使用的“对象”表示(反之亦然)。
这是一个带有基本消息类的简化示例,然后根据“类型”标头,存在更多数据/函数,我们必须选择正确的子类来实例化:
class BaseMessage {
public:
enum Type {
MyMessageA = 0x5a,
MyMessageB = 0xa5,
};
BaseMessage(Type type) : mType(type) { }
virtual ~BaseMessage() { }
Type type() const { return mType; }
protected:
Type mType;
virtual void parse(void *data, size_t len);
};
class MyMessageA {
public:
MyMessageA() : BaseMessage(MyMessageA) { }
/* message A specific stuf ... */
protected:
virtual void parse(void *data, size_t len);
};
class MyMessageB {
public:
MyMessageB() : BaseMessage(MyMessageB) { }
/* message B specific stuf ... */
protected:
virtual void parse(void *data, size_t len);
};
在一个真实的例子中,会有数百种不同的消息类型,并且可能有几个级别或层次结构,因为一些消息彼此共享字段/功能。
现在,要解析一个字节字符串,我正在做类似的事情:
BaseMessage *msg = NULL;
Type type = (Type)data[0];
switch (type) {
case MyMessageA:
msg = new MyMessageA();
break;
case MyMessageB:
msg = new MyMessageB();
break;
default:
/* protocol error */
}
if (msg)
msg->parse(data, len);
但是我觉得这个巨大的开关不是很优雅,而且我有两次关于哪个消息具有哪个“类型值”的信息(一次在构造函数中,一次在此开关中)它也很长......
我正在寻找一种更好的方法,它会更好......如何改进这个?