Quelques raccourcis :
Ceci est un exemple implémentant (de manière simpliste) le schéma de conception Observateur en C#. Vous pourrez comparer par vous-mêmes avec des programmes équivalents dans les langages que vous connaissez.
Le schéma de conception Observateur est un système d'abonnement :
Pour en savoir plus : ../Developpement/Schemas-conception.html#observateur
Notre exemple sera celui d'un petit serveur de touches lues au clavier : ce serveur lira les touches pressées et en informera les abonnés, qui agiront en conséquence. Certains abonnés feront écho à l'écran des touches pressées; un abonné particulier signalera la fin du programme sur pression de la touche 'q'.
Dans cette version, les abonnés seront des classes implémentant une interface particulière. Le fournisseur conservera des références vers les abonnés à travers ces interfaces, et appellera les services de l'interface lorsque des événements surviendront.
Le programme principal montre comment il est possible d'abonner quelques observateurs au gestionnaire et de lire, puis d'afficher des touches, de manière cyclique, jusqu'à ce que le signal de fin de programme ait été produit. |
|
L'interface RéactionClavier expose un service TouchePressée(). Ce service sera invoqué lors du rappel des abonnés. |
|
Un cas particulier de RéactionClavier est un AfficheurTouche, qui affichera les touches pressées. |
|
Un Signaleur pourra signaler l'occurrence d'un « événement » (au sens large, pas dans une acception technique). |
|
Un Surveillant surveille une touche en particulier et, si cette touche est pressée, signale un Signaleur. |
|
Un cas particulier de Signaleur est FinDeProgramme, dont le nom décrit bien la tâche. |
|
Un GestionnaireClavier est un singleton implémentant le schéma de conception Observateur. Il est capable de lire une touche et d'informer tous ses abonnées de la touche qui fut lue. |
|
Le défaut de cette approche est qu'elle est intrusive : les abonnés doivent implémenter une interface particulière, ce qui demande une adaptation de leur structure interne, et ce qui mène à du code quelque peu verbeux.
Un délégué est une abstraction de certains langages (en particulier, C# et Delphi, les deux étant l'oeuvre du même concepteur, Anders Hejlsberg) permettant de réaliser du polymorphisme sur la base de la signature d'une fonction, plutôt que sur la base d'une interface.
Le programme principal montre comment il est possible d'abonner quelques observateurs au gestionnaire et de lire, puis d'afficher des touches, de manière cyclique, jusqu'à ce que le signal de fin de programme ait été produit. Vous remarquerez que l'on abonne des méthodes plutôt que des instances dans cette version. |
|
Le délégué RéagirClavier correspond à une fonction void acceptant un char en paramètre; on pourra faire pointer un RéagirClavier sur n'importe quelle méthode (d'instance ou de classe) respectant cette signature. Ceci dictera la signature du service qui sera invoqué lors du rappel des abonnés. |
|
Un cas particulier de RéagirClavier est la méthode TouchePressée d'un AfficheurTouche, qui affichera les touches pressées. Notez que la classe AfficheurTouche n'est plus forcée d'implémenter une interface particulière. Nous avons réduit le couplage dans notre code, ce qui est en général vu comme une avancée. |
|
Le délégué Signaler pourra signaler l'occurrence d'un « événement » (au sens large, pas dans une acception technique). |
|
Un Surveillant surveille une touche en particulier et, si cette touche est pressée, le signale à travers un délégué de type Signaler. |
|
Un cas particulier de délégué de type Signaler est la méthode Signaler d'une instance de FinDeProgramme. |
|
Un GestionnaireClavier est un singleton implémentant le schéma de conception Observateur. Il est capable de lire une touche et d'informer tous ses abonnées de la touche qui fut lue. Portez attention aux rappels faits dans la méthode Exécuter(), qui sont plus simples sur le plan syntaxique que dans la version par interfaces. |
|
Voilà!