Bien, el contexto es un código de serialización/deserialización que analizará un flujo de bytes en una representación de 'objeto' que es más fácil de trabajar (y viceversa).Elegir la subclase correcta para crear una instancia programática
Aquí hay un ejemplo simplificado con una clase de base de mensaje y luego dependiendo de cabecera de un 'tipo', algunos datos más/función están presentes y hay que elegir la subclase derecho a una instancia:
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);
};
En un verdadero ejemplos, habría cientos de tipos de mensajes diferentes y posiblemente varios niveles o jerarquías porque algunos mensajes comparten campos/funciones entre sí.
Ahora, para analizar una cadena de bytes, lo estoy haciendo algo como:
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);
pero no encuentra este enorme interruptor muy elegante, y tengo la información acerca de qué mensaje tiene el que 'Tipo valor 'dos veces (una vez en el constructor, una en este modificador) También es bastante larga ...
Estoy buscando una mejor manera que simplemente sería mejor ... ¿Alguien tiene alguna idea de cómo mejorar esta ?
Enfoque muy interesante de hecho. El aspecto de la alteración del tiempo de ejecución no es realmente útil en mi caso específico, pero es una buena bonificación que podría ser útil en otros casos. Esperaré un poco para ver si alguien más está antes de confirmar como respondí. – 246tNt
Obviamente, no puede agregar tipos de mensajes en tiempo de ejecución. De todos modos, la caja del interruptor se ha transformado en una línea por cada entrada de registro de tipo de mensaje en el mapa, no veo la gran ganancia aquí, ciertamente no hay menos cantidad de código resultante, ¿más eficiente? Menos desorden, probablemente? –
No me preocupa mucho el rendimiento, no estoy procesando cientos de miles de mensajes por segundo, el estilo de código es más importante aquí. También el triunfo que veo aquí (aunque no sea obvio a partir de la pregunta), es que también puedo agregar otros métodos aparte de 'createMessage' si necesito otra cosa del tipo, como definir qué 'clase de control' manejará el mensaje y esas cosas. Para la alteración del tiempo de ejecución: puede modificar el mapa en tiempo de ejecución. Para agregar nuevos mensajes, puede descargarlos desde objetos compartidos como complementos y demás. – 246tNt