C#: les événements ou un observateur de l'interface? Avantages/inconvénients?
J'ai suivantes (simplifié):
interface IFindFilesObserver
{
void OnFoundFile(FileInfo fileInfo);
void OnFoundDirectory(DirectoryInfo directoryInfo);
}
class FindFiles
{
IFindFilesObserver _observer;
//...
}
...et je suis en conflit. C'est en gros ce que j'aurais écrit en C++, mais le C# a des événements. Dois-je changer le code pour utiliser les événements, ou devrais-je le laisser seul?
Quels sont les avantages ou les inconvénients d'événements sur une traditionnelle observateur de l'interface?
Vous devez vous connecter pour publier un commentaire.
Penser à un évènement, à un rappel de l'interface où l'interface a une seule méthode.
Seule crochet événements dont vous avez besoin
Avec les événements que vous avez seulement besoin de mettre en œuvre des gestionnaires pour les événements qui vous intéressent dans la manipulation. Dans l'observateur de l'interface de modèle, vous auriez à mettre en œuvre toutes les méthodes dans l'ensemble de l'interface, y compris la mise en œuvre de la méthode d'organes pour les types de notifications que vous n'avez pas de soins sur la manipulation. Dans votre exemple, vous avez toujours à mettre en œuvre OnFoundDirectory et OnFoundFile, même si vous ne se soucient l'un de ces événements.
Moins d'entretien
Une autre bonne chose à propos des événements, vous pouvez en ajouter un nouveau à une classe particulière de sorte que cela va augmenter, et vous n'avez pas à changer tous les observateurs. Tandis que si vous voulez ajouter une nouvelle méthode à une interface, vous devez aller autour de chaque classe qui implémente déjà que l'interface et de mettre en œuvre la nouvelle méthode dans chacun d'eux. Avec un événement, vous avez seulement besoin de modifier les classes qui veulent réellement faire quelque chose en réponse à la nouvelle de l'événement que vous ajoutez.
Le modèle est intégré dans la langue pour que tout le monde sait comment l'utiliser
Les événements sont idiomatiques, en ce que lorsque vous voyez un événement, vous savez comment l'utiliser. Avec un observateur de l'interface, les gens ont souvent de mettre en œuvre différentes façons de s'inscrire pour recevoir des notifications ainsi que le raccordement de l'observateur.. avec des événements bien que, une fois que vous avez appris à vous inscrire et utiliser une (avec l'opérateur+=), le reste sont tous les mêmes.
Pros pour les interfaces
Je n'ai pas beaucoup de pros pour des interfaces. Je suppose qu'ils se forcer quelqu'un à afin de mettre en œuvre toutes les méthodes de l'interface. Mais, vous ne pouvez pas vraiment forcer quelqu'un à mettre en œuvre toutes ces méthodes correctement, donc je ne pense pas qu'il y a beaucoup de valeur sur ce.
Syntaxe
Certaines personnes n'aiment pas la façon dont vous devez déclarer un type délégué pour chaque événement. Aussi, la norme de gestionnaires d'événements dans le .Net framework suivez ces paramètres: (object sender, EventArgs args). Comme expéditeur ne pas spécifier un type particulier, vous avez à bas-en fonte si vous voulez l'utiliser. C'est souvent fine, dans la pratique, si elle ne se sent pas tout à fait juste parce que vous êtes de perdre la protection du système de type statique. Mais, si vous mettez en œuvre vos propres événements et de ne pas suivre les .Net framework convention sur cela, vous pouvez utiliser le bon type pour que les bas-casting n'est pas nécessaire.
event Action
ouevent Action<string,int>
etc.Hmm, les événements peuvent être utilisés pour implémenter le pattern observer. En fait, à l'aide d'événements peut être considéré comme une autre de mise en œuvre de l'observateur-modèle à mon humble avis.
Pros de l'interface de la solution:
Contre:
Certains autres avantages d'événements.
Vous pouvez atteindre tous ces objectifs (à l'exception de la chaîne d'outils) vous-même, mais il est étonnamment difficile. Par exemple:
Si vous utilisez une variable de membre comme une Liste<> pour stocker la liste des observateurs.
Si vous utilisez une boucle foreach pour parcourir il alors toute tentative d'ajouter ou de supprimer un abonné dans un délai d'un des OnFoo() la méthode des rappels déclenchera une exception, à moins que vous écrire plus de code pour gérer proprement.
Événements sont 2x fois plus lent que la simple appel de fonction, 3x plus lent si vous n'null check sur chaque augmentation, et copie délégué d'événement avant null check et l'invocation à faire thread-safe.
Aussi lire MSDN sur les nouvelles (dans la version 4.0)
IObserver<T>
de l'interface.Considérons cet exemple:
Pros sont que les événements sont plus "dot-netty'. Si vous êtes à la conception de composants non visuels qui peuvent être déposés sur un formulaire, vous pouvez les connecter à l'aide de la designer.
Les inconvénients sont qu'un événement signifie uniquement un seul événement - vous besoin d'un événement distinct pour chaque "chose" que vous souhaitez notifier à la personne. Ce n'est pas vraiment beaucoup d'impact pratique, sauf que chaque objet observé aurait besoin pour maintenir une référence pour tout observateur pour chaque événement, des ballonnements, de la mémoire dans le cas où il y a beaucoup d'objets observés (l'une des raisons, ils ont fait une gestion différente de l'observateur/observable relation dans WPF).
Dans votre cas, je dirais qu'il n'a pas beaucoup de différence. Si l'observateur peut généralement être intéressé par tous ces événements, l'utilisation d'un observateur de l'interface plutôt que de les séparer des événements.
Java a la langue de support de l'anonymat des interfaces, donc de rappel interfaces sont la chose de l'utiliser en Java.
C# a un support pour les délégués anonymes - lambda - et donc les événements sont la chose à utiliser en C#.
La meilleure façon de décider est ceci: ce qui convient à la situation. Cela peut sembler comme un idiot ou peu serviable réponse, mais je ne pense pas que vous devriez penser à l'un ou l'autre comme la "bonne" solution.
Nous pouvons jeter une centaine de conseils à vous. Les événements sont meilleures lorsque l'observateur est prévue pour écouter arbitraire des événements. Une interface est meilleure lorsque l'observateur devrait énumérées à l'ensemble d'une série d'événements. Les événements sont meilleurs lorsqu'ils traitent avec des applications à interface graphique. Les Interfaces de consommer moins de mémoire (un seul pointeur pour plusieurs événements). Yadda yadda yadda. Une liste des avantages et des inconvénients est quelque chose à penser, mais pas de réponse définitive. Ce que vous avez vraiment besoin de faire est d'essayer les deux d'entre eux dans les applications réelles et d'obtenir une bonne sensation pour eux. Ensuite, vous pouvez choisir celui qui convient à la situation. Apprendre de le faire.
Si vous devez utiliser une seule définition de la question, puis demandez-vous qui décrit votre situation: Un ensemble de vaguement liés, les événements qui pourront être utilisés ou ignorés, ou un ensemble de étroitement liés à des événements qui ont généralement besoin d'être manipulé par un observateur. Mais alors, je suis juste la description de l'événement le modèle et le modèle d'interface, donc je suis de retour à la case départ: lequel est le mieux adapté à la situation mieux?
Une prestation d'interfaces, c'est qu'ils sont plus faciles à appliquer les décorateurs d'. L'exemple standard:
par rapport à:
(Je suis un grand fan de la décoratrice modèle).
Je préfère un événement solution de base pour les raisons suivantes
Si vos objets doivent être sérialisé en quelque sorte, qui conserve les références comme avec NetDataContractSerializer ou peut-être protobuf événements ne seront pas en mesure de traverser la sérialisation des limites. Depuis observateur modèle repose sur rien de plus que de simplement les références de l'objet, il peut travailler avec ce type de sérialisation avec pas de problème si c'est ce qui est souhaité.
Ex. Vous avez un tas de business objects qui relient les uns aux autres de façon bidirectionnelle que vous avez besoin pour passer à un service web.