Quels sont les avantages du modèle délégué par rapport au modèle observateur?

9

Dans le modèle délégué , un seul objet peut écouter directement les événements d'un autre objet. Dans le modèle d'observateur , un nombre quelconque d'objets peuvent écouter les événements d'un objet particulier. Lors de la conception d'une classe qui doit notifier d'autres objets d'événements, pourquoi utiliseriez-vous jamais le modèle délégué sur le modèle observateur? Je vois le modèle d'observateur comme plus flexible. Vous ne pouvez avoir qu'un seul observateur maintenant, mais une future conception peut nécessiter plusieurs observateurs.

JoJo
la source
4
Qu'entendez-vous par «modèle de délégué»? Si vous parlez de quelque chose comme les délégués de .net, vous pouvez avoir autant d'abonnés que vous le souhaitez.
CodesInChaos
Lié, mais plus axé sur Cocoa: NSNotificationCenter vs délégation (à l'aide de protocoles)?
mouviciel

Réponses:

7

Il n'y a pas de modèle de délégué en soi. Je vais supposer que vous voulez dire le modèle de délégation .

Si je comprends bien, ils sont complètement inversés et utilisés à des fins différentes.

Généralement, avec un modèle d'observateur , un nombre quelconque d'objets observateurs écoutent un événement sur un deuxième objet et agissent sur l'événement. Le deuxième objet n'a aucune connaissance de ses auditeurs. Cela les interpelle simplement.

Un objet délégué est passé au deuxième objet qui appelle des méthodes directement sur le délégué. Et c'est là que réside l'avantage que vous recherchez. Plutôt que d'envoyer un seul message à plusieurs écouteurs, il a un contrôle complet sur un seul objet (à un moment donné). Voir aussi Inversion de contrôle .

pdr
la source
6

Vous regardez les choses de manière incorrecte. Un observateur voit qu'un événement particulier se produit. Il n'a aucun impact ni propriété. Un délégué gère un événement particulier et a la propriété du gestionnaire, même si le délégant possède l'interface de l'événement.

Telastyn
la source
1
Un délégué n'est vraiment rien de plus qu'un observateur d'un événement. Un délégué n'a pas besoin de "gérer" quoi que ce soit. Il ne peut rien faire en toute sécurité et n'affectera pas (ou du moins ne devrait pas) affecter l'instance qui a déclenché l'événement.
Marjan Venema
5
@MarjanVenema - si l' objet A ne déléguera la responsabilité de l'événement à l' objet B, vous n'êtes pas en utilisant le modèle de délégation: vous utilisez le modèle d'observation avec un seul observateur.
Telastyn
Oui, c'est à ça que je pensais. J'ai cru comprendre que les types de signature d'événement devaient être utilisés par l'abonné d'un événement «OnWthing». Apparemment, les délégués en C # ne sont pas un seul abonné comme ils le sont par exemple dans Delphi.
Marjan Venema
@Marjan Venema "Un délégué n'est vraiment rien de plus qu'un observateur d'un événement." - cela dépend de la langue dont vous parlez. Dans l'objectif C, certains délégués sont chargés de fournir des données - par exemple, des délégués de données - et un objet auquel il manque un délégué de données n'a aucune donnée à présenter. Dans ces cas, il y a délégation, distincte du simple fait d'observer quelque chose.
occulus
1
@occulus: merci pour la clarification. Dommage que les langues ne puissent pas s'entendre sur la terminologie ... Parler de programmation d'une manière indépendante du langage devient un peu difficile quand les gens comprennent différentes choses pour les mêmes mots.
Marjan Venema
4

C'est une question de plusieurs compromis.

Compromis:

  • flexibilité (en termes de n> 1 délégués / observateurs)
  • coût d'envoi d'un message
  • résilience (capacité à maintenir l'indisponibilité des délégués / observateurs)
  • facilité d'utilisation

Modèle de délégué:

  • pas très flexible - l'ajout de plus d'un délégué n'est pas possible (implique une certaine forme de "multi-délégué" c'est-à-dire un modèle d'observateur)
  • envoyer un message est bon marché, O (1) - même coût que d'appeler toute autre fonction ou méthode (aucune recherche, file d'attente de messages ou autre infrastructure requise)
  • généralement pas résilient - les délégués sont censés être présents et faire leur part du travail, c'est-à-dire que l'expéditeur a tendance à échouer si le délégué n'est pas connu
  • facile à saisir, facile à mettre en œuvre

Modèle d'observateur:

  • très flexible - l'ajout de n> 1 observateurs est prévu par conception
  • l'envoi d'un message a un coût induit par le nombre d'observateurs, O (n), c'est-à-dire que n observateurs prennent n temps et messages (au moins dans une implémentation naïve)
  • généralement résilient - les observateurs ne sont généralement pas censés faire de travail sur une partie de l'expéditeur. C'est même s'il n'y a pas d'observateur que l'expéditeur n'est pas affecté
  • peut devenir assez complexe à saisir, en particulier les observateurs sont censés réagir aux messages (l'ordre importe-t-il?, quel observateur réagit de quelle manière?)
miraculixx
la source
1

Si je comprends bien, le modèle de délégué est connu sous le nom de mécanisme de gestionnaire d'événements dans d'autres langages, par exemple Delphi. En tant que tel, il s'agit simplement d'une implémentation du modèle d'observation avec une restriction majeure: un seul auditeur à la fois.

L'inconvénient des gestionnaires d'événements ou des délégués est évident: un seul observateur.

L'avantage n'est pas si évident: les performances. Avec un modèle d'observateur, vous pouvez ajouter de nombreux observateurs. Lorsqu'un événement se produit et que les observateurs doivent être informés, vous devrez énumérer les observateurs et envoyer une notification à chacun. Cela peut rapidement embourber toute instance observée, en particulier lorsque le nombre d'événements qui nécessitent une notification est également important.

Marjan Venema
la source
Hein? Le délégué C # n'est que la signature d'une méthode en tant que type de variable (équivalent, par exemple, int (*my_int_f)(int)en C). J'ai toujours pensé qu'ils auraient rendu cela plus facile à comprendre en le faisant fonctionner plus comme struct / enum. Un événement est un point d'ancrage pour un ensemble flexible d'auditeurs, utilisant une seule signature de délégué. Vous pouvez le faire sans événement (c'est pourquoi je suppose que le modèle de délégation signifiait OP, ce qui est très différent), mais la langue vous facilite la tâche.
pdr
hmm. Pas encore très bien versé en C #. J'ai compris que les délégués étaient l'équivalent des types de signature d'événement utilisés par les événements "OnWwhat" dans Delphi par exemple. Ainsi, les événements C # peuvent être abonnés à plusieurs auditeurs?
Marjan Venema
L'action générique <T> est un délégué. Cela n'a rien à voir avec les événements, c'est une variable qui se transmet. Et oui, plusieurs auditeurs peuvent écouter un événement.
pdr
ok merci, j'espère que je peux garder les choses droites ... :-) A retiré la référence C # et s'est concentré davantage sur le mécanisme de l'événement.
Marjan Venema
1

Ceci est un ancien article, mais je vais quand même carillon car les autres réponses ne traitent pas de ce qui se passe lors de l'utilisation de l'un ou l'autre modèle, elles semblent être plus sur la théorie que sur la pratique.

Fonctionnement de la délégation et de l'observateur

Avec Délégation, le délégant choisit exactement qui va répondre à un événement particulier au moment où la source de l'événement potentiel est créée. Vous pourriez considérer cet auditeur comme un seul observateur . Dans le cas du modèle Observateur, l'observateur choisit qui il observe chaque fois qu'il en a envie; de sorte que les dépendances sont inversées en ce qui concerne l'observateur par rapport à la délégation. Avec le modèle des observateurs, pensez à un journal et aux abonnés comme des observateurs. Les observateurs contrôlent le moment où la relation est créée. Avec délégation, pensez à un employé et à un employeur. L'employeur contrôle le moment où la relation est créée et exactement qui est en charge d'événements spécifiques. Les employés ne peuvent pas choisir les tâches sur lesquelles ils travaillent ... en général.

Certains soutiennent que la délégation peut avoir un observateur mais je pense que la vraie différence entre les deux est la façon dont la gestion des événements est affectée. Vous ne verrez jamais un délégué s'inscrire à un événement. Il ne saura jamais sa gestion de l'événement jusqu'à ce qu'il se produise et le délégant appelle une méthode publique à ce sujet.

Avantage de la délégation

Ce modèle est très rigide et avec la plupart des conceptions regid, il est plus simple et généralement plus robuste. Il vous oblige à déclarer votre gestionnaire d'événements à l'avance au moment de l'initialisation de la source de l'événement potentiel. Si vous avez besoin de quelqu'un pour diriger la circulation, affectez un directeur de la circulation avant d'ouvrir la rue. Dans le cas de l'observateur, vous laisseriez le policier chargé du trafic choisir le moment de diriger le trafic chaque fois qu'il en aurait envie.

Inconvénient de la délégation

L'inconvénient de cette conception est qu'elle n'est pas flexible. Si vous implémentez un code pour vous abonner à un journal, le journal / le délégué devra identifier exactement qui peut lire les articles dès leur création. Avec le modèle d'observateur, ils peuvent être enregistrés plus tard à tout moment et le journal n'aura qu'à savoir qu'une nouvelle personne s'est inscrite.

Quand choisir la délégation?

Lorsque vous avez besoin d'un ou de plusieurs observateurs spécifiques et que vous n'avez aucune raison de changer qui observe, la conception rigide du modèle de délégation sera bénéfique.

Par exemple, vous avez besoin d'une classe / d'un objet pour gérer la création d'une fenêtre contextuelle pour une erreur spécifique. Il n'y a pas beaucoup de raisons pour lesquelles au moment de l'exécution, vous devrez changer la personne qui gère une erreur spécifique, il serait donc judicieux de déléguer l'erreur «Mémoire insuffisante» à une seule entité. La création d'un tableau de gestionnaires potentiels, puis leur enregistrement pour l'erreur "Mémoire insuffisante" n'aurait pas beaucoup de sens; ce serait un exemple d'utilisation du modèle d'observateur dans cette situation. Au moment de l'exécution, vous souhaiterez peut-être modifier les méthodes appelées ou le «délégué» appelé pour les événements variables, mais il n'est pas normal de remplacer un gestionnaire d'événements par un événement spécifique au moment de l'exécution.

Il n'est pas impossible d'échanger des délégués comme vous le feriez dans le modèle d'observateur, c'est juste compliqué. Dans le monde réel, vous pouvez peut-être échanger des agents de la circulation afin qu'un nouveau délégué gère le trafic. On pourrait dire qu'une meilleure conception ferait du délégué d'origine un poste de police et non un seul officier de police, mais je m'éloigne du sujet ...

Usman Mutawakil
la source