OK、コンテキストは、バイトストリームを解析して、操作しやすい「オブジェクト」表現に変換するシリアライゼーション/デシリアライゼーションコードです (逆も同様です)。
以下は、基本メッセージ クラスを使用した単純化された例です。次に、「タイプ」ヘッダーに応じて、さらにいくつかのデータ/関数が存在するため、インスタンス化する適切なサブクラスを選択する必要があります。
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);
しかし、私はこの巨大なスイッチが非常に洗練されているとは思いません。また、どのメッセージがどの「型の値」を持つかについての情報を 2 回 (コンストラクターで 1 回、このスイッチで 1 回) 持っています。
より良い方法を探しています...これを改善するにはどうすればよいですか?