2011-03-15 16 views
5

Estoy aprendiendo acerca de los patrones de diseño y una cosa que noté en casi todas las implementaciones de ejemplo del patrón Observer es que no hay realmente ningún manejo de errores en los métodos de registro/anulación de registro del Sujeto. Esto me hizo preguntarme cómo/si esto se hace.¿Cuáles son los mecanismos comunes de manejo de errores para el patrón Observer?

La manera específica de manejar los errores dependerá de las necesidades de la aplicación, pero ¿cuáles son las formas más comunes de manejar ese tipo de error?

Por ejemplo, intento registrar un Observer pero el registro falla. ¿Se produce ese error de forma silenciosa y es aceptable que ese Observer en particular simplemente no obtenga actualizaciones? El sujeto no es más inteligente, creo, y puede seguir notificando a los observadores que se registraron con éxito.

Me he dado cuenta de que a veces tengo dificultades para juzgar cuánto control de errores es suficiente en un programa y me pregunto si este es uno de esos casos en los que estoy pensando en cada contingencia.

+0

+1 Buena pregunta – Nilesh

Respuesta

2

Si el registro del Observer falla, definitivamente deberías generar algún error. El cliente de su código espera ser notificado sobre los cambios en el Sujeto y debe poder reaccionar cuando no puede hacerlo. Pero si no se registra un observador, no debe afectar a los demás sujetos y en absoluto. De hecho, es posible que incluso tenga un observador para registro de observador fallido eventos - meta-observador ;-).

Pero aspecto mucho más interesante En mi humilde opinión, ¿qué debería pasar cuando Observer arroja una excepción desde su método notify? ¿Debería llamarse al resto de los observadores? ¿Debería eliminarse este observador? ¿Quién es responsable de este error? ¿Y dónde manejarlo?

Existen algunos otros patrones de diseño que solucionan este problema. Puede usar Decorator y ajustar todos y cada uno de los Observer capturando excepciones lanzadas desde notify y tragándolas (ekhem, logging). El sujeto ni siquiera lo notará, lo cual está bien. Además, otros observadores no serán interrumpidos porque la excepción se detecta lo suficientemente temprano.

También considere Composite para envolver todos los observadores en un solo, virtual uno. Luego decora esto en la excepción antes mencionada capturando al observador. Parece similar, pero la excepción arrojada por un observador evitará que se llame a otro observador. Ahora incluso puede formar jerarquías ...

1

Notificar a los controladores de los observadores que casi nunca deberían filtrar excepciones, porque la única entidad que normalmente estaría más interesada en una excepción es el observador que la está lanzando. Una excepción normalmente significa, en esencia, "No pude hacer lo que solicitó porque X". A un sujeto observable generalmente no le importará que los manejadores de eventos hagan algo, por lo que no les importaría si no lo hacen. Por otro lado, si una excepción significa que las invariantes de clase del sujeto ya no se cumplen, entonces una excepción es probablemente un mal necesario.

Si se envía una excepción desde un controlador de notificación, se debe considerar muy en serio (si se trata de una cosa estúpida que no debería haber quedado atrapada en el manejador, eso debería arreglarse seriamente). Sin embargo, el patrón normal de evento de Microsoft de omitir todos los controladores de eventos después del primero que arroja una excepción es muy malo. Un enfoque mucho mejor sería ejecutar todos los controladores de eventos, capturando todas las excepciones a medida que ocurren y agregándolas a una lista, y luego al final, si la lista no está vacía, lanzando una EventHandlerException que contiene una lista de todas las excepciones que ocurrido durante el procesamiento del evento.

Cuestiones relacionadas