Le modèle de «centre de notification» encourage-t-il une bonne ou une mauvaise conception de programme?


13

Parfois, je rencontre ces API de type hub de message, par exemple Cocoa NSNotificationCenter: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

Habituellement, ces API fournissent un point d'accès global sur lequel vous vous abonnez ou diffusez des messages / événements. Je pense que c'est un problème car cela encourage une architecture de programme plate et non structurée, où les dépendances ne sont pas explicites dans l'API, mais cachées dans le code source. Vous n'êtes pas obligé de penser à la propriété et aux hiérarchies des objets, mais vous pouvez plutôt faire en sorte que n'importe quel objet de votre programme entraîne l'appel de n'importe quel code. Mais c'est peut-être une bonne chose?

Ce modèle encourage-t-il généralement une bonne ou une mauvaise conception de programme, et pourquoi? Cela rend-il le code plus difficile ou plus facile à tester?

Pardonnez-moi si cette question est trop vague ou trop large. J'essaie de comprendre les conséquences potentielles d'une utilisation extensive d'une API comme celle-ci, et les différentes façons dont vous pouvez l'utiliser.

Edit: Je suppose que mon plus gros problème avec ce modèle est que l'API "ment" sur les dépendances et les couplages d'objets, et peut être illustrée par cet exemple:

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

Vous interrogez cet exemple en particulier ou le modèle d'auditeur en général?
TheLQ

Je crois que cela est plus large que le modèle d'auditeur. Le modèle d'écouteur peut être implémenté "proprement" avec une structure d'objet bien définie et l'enregistrement d'écouteurs sur des objets spécifiques. Mon incertitude concerne le modèle global de hub de message / événement.
Magnus Wolffelt

Réponses:


6

Je n'irais pas jusqu'à dire que cela encourage une mauvaise programmation. Mais il peut facilement être mal utilisé.

Eh bien, quelle est l'idée réelle?
La source de la notification ne fait que sa notification. Il ne fait aucune hypothèse sur l'existence d'observateurs potentiels ou quoi que ce soit. Un observateur s'inscrit pour les notifications qu'il est conçu pour gérer. L'observateur ne fait aucune hypothèse sur le nombre de sources potentielles pour les notifications qu'il peut gérer.

C'est un moyen de réaliser une injection de dépendance, sans que les sources connaissent les observateurs ou que les observateurs connaissent les sources. Cependant, pour que tout le système fonctionne, vous devez câbler les bons observateurs pour les bonnes notifications, et ce système est même vulnérable aux fautes de frappe, car il ne peut pas être vérifié lors de la compilation.

Le plus grand danger est bien sûr que quelqu'un l'utilise pour rendre des tonnes d'objets disponibles dans le monde entier pour les appels 1-1.


6

La messagerie asynchrone est un bon principe architectural pour les grands systèmes qui doivent évoluer

L'équivalent Java de ceci est JMS et généralement considéré comme une bonne chose .

En effet, cela favorise le découplage de votre code client du code qui dessert réellement le message. Le code client doit simplement savoir où publier son message. Le code de service doit simplement savoir où récupérer les messages. Le client et le service ne se connaissent pas et peuvent donc changer indépendamment l'un de l'autre selon les besoins.

Vous pouvez facilement externaliser l'URI du concentrateur de messages pour le rendre configurable et non incorporé dans le code source.


4

Il s'agit d'une implémentation de modèle Oberserver typique (ou parfois appelée modèle Listener ou parfois appelée modèle Subscriber / Publisher). Dans les applications où ce comportement est utile, c'est un bon modèle à mettre en œuvre. Aucun modèle ne doit être implémenté s'il n'ajoute aucune valeur à la solution.

D'après votre question, il semble que vous craignez que tout soit au courant du NotificationCenter et que les choses globales soient MAUVAISES. Parfois, oui, les choses globales sont mauvaises. Mais regardons l'alternative. Disons que vous avez 2 composants, pour cet exemple, peu importe ce qu'ils font ou ce qu'ils sont. Le composant 1 contient des données qui ont été traitées ou modifiées d'une manière ou d'une autre. Component2 souhaite être informé de toute modification des données du type géré par Compoent1. Le composant 2 doit-il connaître l'existence du composant 1? Ou serait-il préférable pour Component2 de s'abonner / écouter un message qui lui indique qu'un composant quelque part dans l'application a changé certaines données qui l'intéressent? Maintenant, prenez cet exemple et multipliez-le par des dizaines ou plus de composants et vous pouvez voir où se trouve la valeur du motif.

Est-ce une solution parfaite pour chaque situation, non. Est-ce qu'il résume la communication entre les composants et fournit un couplage plus lâche, oui.


1
En lisant sur wikipedia, la définition du modèle d'observateur ne semble pas inclure un hub d'événements mondialement disponible. Si le hub d'événements était passé dans le constructeur / méthode de tous les objets concernés, je considérerais cela comme un bon modèle. C'est en effet le point d'accès global et son état qui me rend incertain.
Magnus Wolffelt

0

C'est bon pour les systèmes événementiels et c'est plus agréable que l'alternative d'avoir un groupe d'observateurs qui s'observent, car vous êtes moins susceptible de vous retrouver avec des boucles infinies par inadvertance d'observateurs qui déclenchent des événements. C'était un vrai problème dans les anciens jours VB, lorsque vous disposiez de contrôles ActiveX pilotés par les événements qui pouvaient être connectés les uns aux autres avec des gestionnaires d'événements.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.