¿El patrón del "centro de notificaciones" fomenta el diseño del programa bueno o malo?

13

A veces me encuentro con estas API de centro de mensajes, por ejemplo, Cocoa NSNotificationCenter: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

Por lo general, estas API proporcionan un punto de acceso global en el que se suscribe o transmite mensajes / eventos. Estoy pensando que esto es un problema porque fomenta una arquitectura de programa plana y no estructurada, donde las dependencias no son explícitas en la API, sino que están ocultas en el código fuente. No está obligado a pensar en la propiedad y las jerarquías de los objetos, sino que puede hacer que cualquier objeto en su programa provoque que se llame a cualquier código en cualquier lugar. Pero tal vez esto es algo bueno?

¿Este patrón generalmente fomenta el diseño de un programa bueno o malo, y por qué? ¿Hace que el código sea más difícil o más fácil de probar?

Perdóname si esta pregunta es demasiado vaga o amplia. Estoy tratando de entender las posibles consecuencias del uso extensivo de una API como esta, y las diferentes formas en que podría usarla.

Editar: Supongo que mi mayor problema con este patrón es que la API "miente" sobre las dependencias y los acoplamientos de objetos, y puede ilustrarse con este ejemplo:

myObj = new Foo();
myOtherObj = new Bar();
print myOtherObj.someValue; // prints 0
myObj.doSomething();
print myOtherObj.someValue; // prints 1, unexpectedly, because I never indicated that these objects had anything to do with each other
Magnus Wolffelt
fuente
¿Se cuestiona este ejemplo específicamente o el patrón de escucha en general?
TheLQ
Creo que esto es más amplio que el patrón de escucha. El patrón de escucha puede implementarse "limpiamente" con una estructura de objeto bien definida y registrando oyentes en objetos específicos. Mi incertidumbre es sobre el patrón global del centro de mensajes / eventos.
Magnus Wolffelt

Respuestas:

6

No iría tan lejos como para decir que fomenta la mala programación. Pero puede ser mal utilizado fácilmente.

Bueno, ¿cuál es la idea real?
La fuente de la notificación solo hace su notificación. No asume la existencia de observadores potenciales ni nada. Un observador se registra para las notificaciones que está diseñado para manejar. El observador no hace suposiciones sobre cuántas fuentes potenciales hay para las notificaciones que puede manejar.

Esta es una forma de lograr la inyección de dependencia, sin que las fuentes conozcan a los observadores o los observadores conozcan las fuentes. Sin embargo, para que todo el sistema funcione, debe conectar a los observadores correctos para las notificaciones correctas, y este sistema es incluso vulnerable a los errores tipográficos, ya que no se puede verificar el tiempo de compilación.

El mayor peligro, por supuesto, es que alguien lo use para hacer que toneladas de objetos estén disponibles globalmente para llamadas 1-1.

back2dos
fuente
6

La mensajería asincrónica es un buen principio arquitectónico para sistemas grandes que deben escalar

El equivalente de Java de esto es JMS y generalmente se considera algo bueno .

Esto se debe a que promueve el desacoplamiento de su código de cliente del código que realmente sirve el mensaje. El código del cliente simplemente tiene que saber dónde publicar su mensaje. El código de servicio simplemente tiene que saber dónde recoger los mensajes. El cliente y el servicio no se conocen entre sí y, por lo tanto, pueden cambiar independientemente uno del otro según sea necesario.

Puede externalizar fácilmente el URI del centro de mensajes para hacerlo configurable y no incrustado en el código fuente.

Gary Rowe
fuente
4

Esta es una implementación típica del patrón Oberserver (o a veces se llama un patrón de escucha o a veces se llama patrón de suscriptor / editor). En aplicaciones donde este comportamiento es útil, es un buen patrón para implementar. No se debe implementar ningún patrón si no agrega valor a la solución.

Según su pregunta, parece que le preocupa que todo sepa sobre NotificationCenter y que las cosas globales son MALAS. A veces, sí, las cosas globales son malas. Pero veamos la alternativa. Digamos que tiene 2 componentes, para este ejemplo realmente no importa lo que hacen o lo que son. Component1 tiene algunos datos que se actuaron o cambiaron de alguna manera. Component2 quisiera saber sobre cualquier cambio en los datos del tipo que Compoent1 administra. ¿Debe Component2 saber sobre la existencia de Component1? ¿O sería mejor para Component2 suscribirse / escuchar un mensaje que le dice que algún componente en algún lugar de la aplicación cambió algunos datos que le interesan? Ahora tome este ejemplo y multiplíquelo por docenas o más componentes y podrá ver dónde reside el valor del patrón.

¿Es una solución perfecta para cada situación, no. ¿Abstracta la comunicación entre los componentes y proporciona un acoplamiento más suelto, sí?

Walter
fuente
1
Leyendo en wikipedia, la definición del patrón de observador no parece incluir un centro de eventos disponible a nivel mundial. Si el centro de eventos se pasó al constructor / método de todos los objetos en cuestión, consideraría que este es un buen patrón. De hecho, es el punto de acceso global y su estado lo que me hace dudar.
Magnus Wolffelt
0

Es bueno para los sistemas controlados por eventos, y es mejor que la alternativa de tener un grupo de Observadores observándose, ya que es menos probable que termines con bucles infinitos inadvertidos de observadores disparando eventos. Este era un problema real en los viejos días de VB, cuando tenía controles ActiveX controlados por eventos que podían conectarse entre sí con controladores de eventos.

TMN
fuente