Citando directamente de the paper:
para ilustrar los problemas concretos del patrón de observador, empezamos con una simple y ubicua ejemplo: arrastre de ratón. El siguiente ejemplo rastrea los movimientos del mouse durante una operación de arrastre en un objeto Path
y muestra en la pantalla. Para simplificar, utilizamos los cierres Scala como observadores.
var path: Path = null
val moveObserver = { (event: MouseEvent) =>
path.lineTo(event.position)
draw(path)
}
control.addMouseDownObserver { event =>
path = new Path(event.position)
control.addMouseMoveObserver(moveObserver)
}
control.addMouseUpObserver { event =>
control.removeMouseMoveObserver(moveObserver)
path.close()
draw(path)
}
En el ejemplo anterior, y como vamos a discutir el observador patrón como se define en [25], en general, viola una impresionante gama de importantes principios de la ingeniería de software:
Efectos secundarios Los observadores promueven efectos secundarios. Como los observadores son apátridas, a menudo necesitamos varios de ellos para simular una máquina de estado como en el ejemplo de arrastre. Tenemos que guardar el estado donde es accesible para todos los observadores involucrados como en la variable path
anterior.
encapsulación Como la variable de estado path
escapa del alcance de los observadores, el patrón de observador rompe la encapsulación.
Compuestabilidad observadores múltiples forman un conjunto disperso de objetos que tienen que ver con una sola preocupación (o múltiple, ver siguiente punto). Dado que múltiples observadores están instalados en puntos diferentes en diferentes momentos, no podemos, por ejemplo, disponerlos fácilmente.
separación de las preocupaciones Los observadores anteriores no sólo pequeñas el camino del ratón, sino también llamar a un comando de dibujo, o más generalmente, incluyen dos preocupaciones diferentes en la misma ubicación del código . A menudo es preferible separar las preocupaciones de construir la ruta y mostrarla, por ejemplo, como en el patrón model-view-controller (MVC) [30].
Escalabilidad Podríamos conseguir una separación de preocupaciones en nuestro ejemplo mediante la creación de una clase para sí mismo caminos que publica eventos cuando cambia la trayectoria. Lamentablemente, no existe una garantía para la coherencia de los datos en el patrón del observador. Supongamos que creamos otro evento publicando el objeto que depende de los cambios en nuestra ruta original, por ejemplo, un rectángulo que representa los límites de nuestra ruta. También considera que un observador está escuchando los cambios tanto en la ruta como en sus límites para dibujar una ruta enmarcada. Este observador debería determinar manualmente si los límites ya están actualizados y, de lo contrario, diferir el funcionamiento del dibujo . De lo contrario, el usuario podría observar un marco en la pantalla que tiene el tamaño incorrecto (un error).
Uniformidad Diferentes métodos para instalar diferentes observadores Disminuir la uniformidad del código.
Abstracción Hay un nivel bajo de abstracción en el ejemplo. Se basa en una interfaz de peso pesado de una clase de control que proporciona más que solo métodos específicos para instalar observadores de eventos de mouse. Por lo tanto, no podemos abstraer sobre las fuentes de eventos precisos. Por ejemplo, podría permitir al usuario abortar una operación de arrastre presionando la tecla escape o usar un dispositivo puntero diferente, como una pantalla táctil o una tableta gráfica.
Gestión de recursos La vida de un observador debe ser administrado por clientes. Por motivos de rendimiento, queremos observar los eventos de movimiento del mouse solo durante una operación de arrastre . Por lo tanto, necesitamos instalar explícitamente y desinstalar el mouse move observer y necesitamos recordar el punto de instalación (control anterior).
distancia semántica En última instancia, el ejemplo es difícil de entender porque el flujo de control se invierte lo que resulta en demasiado código repetitivo que aumenta la semántica distancia entre el programadores intención y el código real.
[25] E. Gamma, R. Helm, R. Johnson y J. Vlissides. Diseño patrones: elementos de software orientado a objetos reutilizables. Addison-Wesley Longman Publishing Co., Inc., Boston, MA, EE.UU., 1995. ISBN 0-201-63361-2.
Discutido aquí también ... http://lambda-the-ultimate.org/node/4028 –