2011-08-19 9 views
5

Estoy usando un marco basado en Eclipse RCP que sufre de un modelo de evento ineficiente. Específicamente, los eventos emitidos por los controles a menudo 'en cascada'. Por ejemplo, un control emitirá un evento COLOR_CHANGED que hace que el compuesto padre propague el evento a controles hermanos, que a su vez deciden emitir sus propios eventos COLOR_CHANGED (en respuesta al evento original), lo que lleva a una especie de reacción en cadena. He creado un perfil de la aplicación que genera más de 100.000 eventos para generar un formulario simple. Francamente, no entiendo cómo no está desbordando la pila.Los eventos están causando una reacción en cadena

Por lo tanto, estoy buscando una técnica o patrón de diseño que evite o reduzca este tipo de comportamiento en cascada. He tenido algunas ideas pero esto no puede ser un problema nuevo; tiene que haber una "mejor práctica" ya para el diseño orientado a eventos.

Mis ideas:

  • Eventos operan como una pila-trace, por lo que nuevos eventos están encadenados a su causa. Esto permite a los oyentes ignorar los eventos que se originaron de ellos mismos. Sin embargo, esto complica mucho mi modelo de eventos (y sería tedioso envolver los eventos estándar de SWT). Sin mencionar que hay casos de uso válidos en los que es posible que desee este comportamiento.
  • Una 'bomba de evento' central se usa para generar eventos. Si un evento tiene el mismo origen y la misma carga que un evento generado anteriormente en los últimos n milisegundos, se descarta. Es de esperar que esto tenga un efecto de dopaje y evite que los eventos caigan en cascada. Obviamente, no puedo controlar cómo se generan los eventos SWT/RCP, pero estos no son mi principal preocupación.
  • Los eventos deben escribirse. Esto parece un paso atrás, pero creo que los eventos más finos ayudarían al rendimiento. Por ejemplo, ValidationFailedEvent en lugar de genérico Event que todo el mundo maneja (y luego tiene que interrogar su estado para determinar el tipo de evento).

Gracias por tomarse el tiempo para leer acerca de mi problema. Todos los consejos/sugerencias son bienvenidos.

EDITAR: Gracias a pablosaraiva, leí sobre Chain-of-responsibility y ahora tienen la siguiente idea:

  • Eventos exponen una propiedad isHandled que, si se establece en true, evitará que el evento se propaguen. Esto debería funcionar cuando se entiende el alcance del evento, pero no ayudará si el evento no puede ser 'manejado' por un único control.
+1

¿Has mirado la cadena de responsabilidad? – pablosaraiva

+0

@pablosaraiva: Parecía prometedor, pero no veo cómo ayudará en el caso de los eventos 'uno-a-muchos', es decir, muchos controles necesitan recibir el evento. – hoipolloi

+0

Usted dice que es "_un marco basado en RCP de Eclipse_" - que debería significar SWT - pero no puedo hacer el resto de la descripción con esto. ¿A qué marco te refieres? –

Respuesta

1

He jugado con muchos enfoques diferentes a lo largo de los años. Lo fundamental que puede hacer para solucionar esto es hacer que los modelos solo emitan eventos si realmente cambian. Esto hace que los modelos sean un poco más complicados para cada clase en el modelo, pero es la única forma en que he logrado hacer que este paradigma funcione.

Por ejemplo

public void setColor(Color c) 
{ 
    setBackground(c); 
    notify(new ColorChangedEvent(this, c)); 
} 

se convertiría en

public void setColour(Color c) 
{ 
    if (!getBackground().equals(c)) 
    { 
     setBackground(c); 
     notify(new ColorChangedEvent(this, c)); 
    } 
} 

Las clases observables estándar en el soporte de Java esto con el método 'setChanged()'.

Una forma un poco más fácil de implementar esto (pero en mi humilde opinión no es tan buena) es hacer que 'notificar' apague la escucha hasta que haya terminado de notificar.Es decir, se parece a notificar

private iAmNotifying; 
public void notify(Event e) 
{ 
    if (!iAmNotifying) 
    { 
     iAmNotifying = true; 
     doTheActualNotification(e); 
     iAmNotifying = false; 
    } 
} 

Pero esto tiene algunos inconvenientes importantes en términos de granularidad, y he tenido más éxito con el primer enfoque.

+0

Ambas excelentes sugerencias. El único inconveniente que puedo imaginar se relaciona con el segundo fragmento, que puede volverse complejo si los eventos se generan de forma asíncrona. – hoipolloi

Cuestiones relacionadas