Partage via


Meilleures pratiques en matière de modèle de conception d’observateur

Dans .NET, le modèle de conception de l’observateur est implémenté en tant qu’ensemble d’interfaces. L’interface System.IObservable<T> représente le fournisseur de données, qui est également responsable de la fourniture d’une IDisposable implémentation qui permet aux observateurs de se désabonner des notifications. L’interface System.IObserver<T> représente l’observateur. Cette rubrique décrit les meilleures pratiques que les développeurs doivent suivre lors de l’implémentation du modèle de conception d’observateur à l’aide de ces interfaces.

Gestion de threads

En règle générale, un fournisseur implémente la IObservable<T>.Subscribe méthode en ajoutant un observateur particulier à une liste d’abonnés représentée par un objet de collection, et il implémente la IDisposable.Dispose méthode en supprimant un observateur particulier de la liste des abonnés. Un observateur peut appeler ces méthodes à tout moment. En outre, étant donné que le contrat fournisseur/observateur ne spécifie pas qui est responsable de se désabonner après la méthode de rappel IObserver<T>.OnCompleted, les deux, le fournisseur et l’observateur, peuvent essayer de supprimer le même membre de la liste. En raison de cette possibilité, les méthodes Subscribe et Dispose doivent être thread-safe. En règle générale, cela implique l’utilisation d’une collection simultanée ou d’un verrou. Les implémentations qui ne sont pas thread-safe doivent documenter explicitement qu’elles ne le sont pas.

Toutes les garanties supplémentaires doivent être spécifiées dans une couche au-dessus du contrat fournisseur/observateur. Les implémenteurs doivent clairement indiquer lorsqu'ils imposent des exigences supplémentaires pour éviter toute confusion de l'utilisateur au sujet du contrat de l'observateur.

Gestion des exceptions

En raison du couplage libre entre un fournisseur de données et un observateur, les exceptions dans le modèle de conception de l’observateur sont destinées à être informationnelles. Cela affecte la façon dont les fournisseurs et les observateurs gèrent les exceptions dans le modèle de conception d’observateur.

Fournisseur : appel de la méthode OnError

La OnError méthode est conçue comme un message d’information pour les observateurs, comme la IObserver<T>.OnNext méthode. Toutefois, la OnNext méthode est conçue pour fournir à un observateur des données actuelles ou mises à jour, tandis que la OnError méthode est conçue pour indiquer que le fournisseur ne peut pas fournir de données valides.

Le fournisseur doit suivre ces bonnes pratiques lors de la gestion des exceptions et de l’appel de la OnError méthode :

  • Le fournisseur doit gérer ses propres exceptions s’il a des exigences spécifiques.

  • Le fournisseur ne doit pas s’attendre à ce que les observateurs gèrent les exceptions d’une manière particulière.

  • Le fournisseur doit appeler la OnError méthode lorsqu’il gère une exception qui compromet sa capacité à fournir des mises à jour. Des informations sur ces exceptions peuvent être transmises à l’observateur. Dans d’autres cas, il n’est pas nécessaire d’informer les observateurs d’une exception.

Une fois que le fournisseur a appelé la méthode OnError ou IObserver<T>.OnCompleted, il ne doit y avoir aucune autre notification et le fournisseur peut annuler l'abonnement de ses observateurs. Toutefois, les observateurs peuvent également se désabonner à tout moment, y compris avant et après avoir reçu une notification OnError ou IObserver<T>.OnCompleted. Le modèle de conception de l’observateur ne détermine pas si le fournisseur ou l’observateur est responsable de se désinscrire ; par conséquent, il est possible que les deux tentent de se désabonner. En règle générale, lorsque les observateurs se désabonnent, ils sont supprimés d’une collection d’abonnés. Dans une application à thread unique, l’implémentation IDisposable.Dispose doit s’assurer qu’une référence d’objet est valide et que l’objet est membre de la collection d’abonnés avant de tenter de le supprimer. Dans une application multithread, un objet de collection thread-safe, tel qu’un objet System.Collections.Concurrent.BlockingCollection<T>, doit être utilisé.

L’observateur : implémentation de la méthode OnError

Lorsqu’un observateur reçoit une notification d’erreur d’un fournisseur, l’observateur doit traiter l’exception comme informationnelle et ne doit pas être tenu de prendre des mesures particulières.

L'observateur doit utiliser ces meilleures pratiques quand il répond à un appel de méthode OnError provenant du fournisseur :

  • L’observateur ne doit pas lever d’exceptions de ses implémentations d’interface, telles que OnNext ou OnError. Toutefois, si l’observateur lève des exceptions, il doit s’attendre à ce que ces exceptions ne soient pas gérées.

  • Pour conserver la pile des appels, un observateur qui souhaite lancer un objet Exception qui a été passé à sa méthode OnError doit envelopper l’exception avant de la lancer. Un objet d’exception standard doit être utilisé à cet effet.

Meilleures pratiques supplémentaires

Tenter d'annuler l'inscription dans la méthode IObservable<T>.Subscribe peut entraîner une référence nulle. Par conséquent, nous vous recommandons d’éviter cette pratique.

Bien qu’il soit possible d’attacher un observateur à plusieurs fournisseurs, le modèle recommandé consiste à attacher une IObserver<T> instance à une IObservable<T> seule instance.

Voir aussi