Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
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.
Cet article décrit les meilleures pratiques à suivre lorsque vous implémentez le modèle de conception d’observateur avec ces interfaces.
Prendre en compte les alternatives avant l’implémentation
Les interfaces IObservable<T> et IObserver<T> conviennent parfaitement aux scénarios de notification push, mais d’autres modèles .NET peuvent être plus adaptés. Pour une notification simple au sein d’une seule application, utilisez des événements. Pour les séquences basées sur l’extraction asynchrone où le consommateur contrôle le rythme, utilisez IAsyncEnumerable<T>. Pour les modèles producteur-consommateur avec rétropression, utilisez System.Threading.Channels. Pour la composition d’événements complexes, le filtrage et la transformation, utilisez le package System.Reactive (Rx.NET) au lieu d’implémenter directement IObservable<T>. Pour plus d’informations, consultez le modèle de conception Observer.
Utiliser un type distinct pour les données de notification
L’objet qui contient les données envoyées par le fournisseur à ses observateurs correspond au paramètre de type générique de IObservable<T> et IObserver<T>. Bien que cet objet puisse être identique à l’implémentation IObservable<T> , définissez-le comme un type distinct. Un type de données dédié conserve les responsabilités du fournisseur séparément de la charge utile de notification et facilite l’évolution de l’API.
Ne vous fiez pas à l’ordre de notification
L’ordre dans lequel les observateurs reçoivent des notifications n’est pas défini. Le fournisseur est libre d’utiliser la méthode de son choix pour déterminer l’ordre ; n’écrivez donc pas d’observateurs qui reposent sur le fait d’être notifiés avant ou après un autre observateur.
Rendre l’abonnement et supprimer thread-safe
En règle générale, un fournisseur implémente la IObservable<T>.Subscribe méthode en ajoutant un observateur à une liste d’abonnés représentée par un objet de collection et en implémentant la méthode en supprimant l’observateur IDisposable.Dispose de cette liste. Un observateur peut appeler ces méthodes à tout moment. Le contrat fournisseur/observateur n’indique pas qui est chargé de se désabonner après la méthode de rappel IObserver<T>.OnCompleted, de sorte que le fournisseur et l’observateur peuvent tous deux essayer de retirer le même membre de la liste.
Pour éviter les situations de concurrence, veillez à ce que les méthodes Subscribe et Dispose soient toutes deux sûres vis-à-vis des threads. 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.
Documenter les garanties de contrat supplémentaires
Spécifiez toutes les garanties supplémentaires dans une couche au-dessus du contrat fournisseur/observateur. Lorsque vous imposez d’autres exigences, indiquez-les clairement afin que les utilisateurs ne soient pas déroutés concernant le contrat de l’observateur.
Gérer les exceptions en tant qu’informations
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. Cette caractéristique affecte la façon dont les fournisseurs et les observateurs gèrent les exceptions.
Appeler OnError uniquement lorsque les mises à jour ne peuvent pas continuer
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 fournit un observateur avec des données actuelles ou mises à jour, tandis que la OnError méthode indique que le fournisseur ne peut pas fournir de données valides.
Suivez ces bonnes pratiques lorsque vous gérez les exceptions et appelez 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. Transmettez des informations sur ces exceptions à 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 devrait plus y avoir d’autres notifications, et le fournisseur peut désinscrire 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 la désinscription. Les deux peuvent donc tenter 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 supprimer l’objet. Dans une application multithreadée, utilisez un verrou pour protéger la collection d’observateurs.
Traiter les notifications OnError comme information dans les observateurs
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.
Suivez ces bonnes pratiques lorsque vous répondez à un OnError appel de méthode à partir d’un fournisseur :
- Ne lèvez pas d’exceptions à partir d’implémentations d’interface telles que OnNext ou OnError. Si l’observateur lève des exceptions, attendez-vous à ce que ces exceptions ne soient pas gérées.
- Pour préserver la pile d’appels, un observateur qui souhaite lever un objet Exception passé à sa méthode OnError doit encapsuler l’exception avant de la lever. Utilisez un objet d’exception standard à cet effet.
Ne pas annuler l’inscription dans la méthode Subscribe
N’essayez pas de désinscrire dans la IObservable<T>.Subscribe méthode, car cela peut entraîner une référence Null.
Attacher un observateur à un seul fournisseur
Bien que vous puissiez attacher un observateur à plusieurs fournisseurs, le modèle recommandé consiste à attacher une IObserver<T> instance à une IObservable<T> seule instance.