¿el castigo siempre es malo?

7

En mi empresa, tenemos muchos "servicios" diferentes que funcionan en paralelo y se envían mensajes entre sí mediante un sistema de mensajería común. Todos los objetos de mensaje se derivan de un objeto genérico común que definimos para mensajería. Cuando cualquier servicio recibe un mensaje, lo primero que debe hacer es bajar el objeto al tipo derivado para que pueda extraer los datos necesarios.

He leído en todo el Internet que no debería tener que bajar un puntero de objeto base a un puntero de objeto derivado y que tener que hacer esto es a menudo una señal de mal diseño. Estoy de acuerdo con este sentimiento para la mayoría de los casos. Y puedo imaginar diferentes diseños para el objeto de mensaje genérico que no requerirían un proceso de conversión. Pero no veo ninguna razón importante para manejar esta situación de manera diferente.

Entonces, mi pregunta general es: ¿es lo malo siempre ser malo? ¿Hay situaciones en las que la difusión es necesaria o aceptable?

    
pregunta c.hughes 11.03.2013 - 17:13

3 respuestas

9

Bajar el puntero a un puntero frente a convertir una carga genérica en un objeto específico son dos cosas diferentes.

La API del sistema de mensajería común debe tener un conjunto de funciones para devolver el objeto exacto que desea, de modo que no esté constantemente abatido en su código de aplicación (que es más propenso a errores).

Básicamente, está hablando de pasar objetos utilizando XML o JSON o algún otro formato de intercambio de datos. No es necesario hablar sobre el downcasting porque ya debería ser manejado por la API del sistema de mensajería común, ya que usted sabe exactamente qué tipo de objetos se están transmitiendo.

Supongo que la API del sistema tiene este aspecto:

GeneralObject* getObject(Message *message);

Debería verse así:

GeneralObject* _getObject(Message *message); // the _ is just to indicate this is a private function that shouldn't be used outside of this module

// these raise exceptions if the object doesn't exist or return null or whatever
Person* getPerson(Message *message);
Place* getPlace(Message *message);

Nunca en tu código usarás la función genérica que devuelve la clase base, siempre usarás el código que devuelve las clases derivadas y dejarás que la API maneje o genere errores si no puede abatirse.

En este caso, la reducción de la velocidad de publicación es básicamente un error al analizar o des-serializar un objeto.

La biblioteca de protobuf de Google tiene un ejemplo de lo que estoy hablando

    
respondido por el Rudolf Olah 11.03.2013 - 17:35
4

Obviamente, si siempre fuera algo malo, no habría necesidad de que el lenguaje apoye la operación. La serialización / mensajería es una gran excepción, ya que el downcast generalmente simplifica enormemente el código, aunque realmente debería construir la conversión en el objeto de la cola de mensajes. Las plantillas suelen ser útiles en ese caso.

La otra situación que he visto donde a menudo son inevitables las bajas es en equals (Object obj) reemplaza, ya que esa firma específica es parte de una interfaz publicada y ampliamente utilizada.

    
respondido por el Karl Bielefeldt 11.03.2013 - 17:52
2

Sí, la reducción es siempre mala. Sí, de vez en cuando se encontrará con escenarios (como construcciones de mensajería) donde las alternativas son peores.

Y por supuesto "peor" es subjetivo. En algunos escenarios, la fragilidad de la conversión descendente es muy inaceptable. En otros, la simplicidad de diseño o legibilidad puede tener mayor prioridad. Al igual que cualquier otra decisión de diseño, es un compromiso que deberá evaluar para su situación.

    
respondido por el Telastyn 11.03.2013 - 17:32

Lea otras preguntas en las etiquetas